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?
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)
Questo è il modo semplice di aggiungere una nuova colonna: df['e'] = e
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())