Aggiungere una nuova colonna a un DataFrame esistente in Python pandas

Ho il seguente DataFrame indicizzato con colonne nominate e righe di numeri non continui:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Vorrei aggiungere una nuova colonna, 'e', al data frame esistente e non voglio cambiare nulla nel data frame (cioè, la nuova colonna ha sempre la stessa lunghezza del DataFrame).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

Ho provato diverse versioni di join, append, merge, ma non ho ottenuto il risultato che volevo, solo errori al massimo. Come posso aggiungere la colonna e all'esempio precedente?

Soluzione

Usa gli indici originali df1 per creare la serie:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)

Modifica 2015 Alcuni hanno segnalato di aver ottenuto il SettingWithCopyWarning con questo codice.
Tuttavia, il codice funziona ancora perfettamente con l'attuale versione 0.16.1 di pandas.

>>> sLength = len(df1['a'])
>>> df1
          a         b         c         d
6 -0.269221 -0.026476  0.997517  1.294385
8  0.917438  0.847941  0.034235 -0.448948

>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e
6 -0.269221 -0.026476  0.997517  1.294385  1.757167
8  0.917438  0.847941  0.034235 -0.448948  2.228131

>>> p.version.short_version
'0.16.1'

Il SettingWithCopyWarning ha lo scopo di informare di una possibile assegnazione non valida su una copia del Dataframe. Non dice necessariamente che hai sbagliato (può innescare falsi positivi) ma dalla 0.13.0 ti fa sapere che ci sono metodi più adeguati per lo stesso scopo. Quindi, se ricevi l'avviso, segui il suo consiglio: Prova ad usare .loc[row_index,col_indexer] = value invece

>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e         f
6 -0.269221 -0.026476  0.997517  1.294385  1.757167 -0.050927
8  0.917438  0.847941  0.034235 -0.448948  2.228131  0.006109
>>> 

Infatti, questo è attualmente il metodo più efficiente come descritto nei docs di pandas


Modifica 2017

Come indicato nei commenti e da @Alexander, attualmente il metodo migliore per aggiungere i valori di una Serie come nuova colonna di un DataFrame potrebbe essere l'utilizzo di assign:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
Commentari (27)

Questo è il modo semplice di aggiungere una nuova colonna: df['e'] = e

Commentari (4)

Farlo direttamente tramite NumPy sarà il più efficiente:

df1['e'] = np.random.randn(sLength)

Notate che il mio suggerimento originale (molto vecchio) era di usare map (che è molto più lento):

df1['e'] = df1['a'].map(lambda x: np.random.random())
Commentari (2)