2014-11-03 9 views
19

Python 3.4 e Pandas 0.15.0Pandas SettingWithCopyWarning

df è un dataframe e col1 è una colonna. Con il codice di seguito, sto controllando la presenza del valore 10 e sostituendo tali valori con 1000.

df.col1[df.col1 == 10] = 1000 

Ecco un altro esempio. Questa volta, sto cambiando i valori in col2 in base all'indice.

df.col2[df.index == 151] = 500 

Entrambi questi producono l'avvertimento di seguito:

-c:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame 

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 

Infine,

cols = ['col1', 'col2', 'col3'] 
df[cols] = df[cols].applymap(some_function) 

Questo produce un avviso simile, con un suggerimento aggiunto:

Try using .loc[row_indexer,col_indexer] = value instead 

I' Non sono sicuro di aver capito il disco l'usanza indicata negli avvertimenti. Quale sarebbe un modo migliore per scrivere queste tre righe di codice?

Si noti che le operazioni hanno funzionato.

risposta

38

Il problema è che: df.col1[df.col1 == 10] restituisce una copia.

Quindi direi:

row_index = df.col1 == 10 
# then with the form .loc[row_indexer,col_indexer] 
df.loc[row_index, 'col1'] = 100 
+0

Grazie. Dovrebbe essere df.loc [row_index, 'col1'] = 100, giusto? –

+1

@ asif.m sono ovviamente corretti al 100%. Lo aggiusterò –

+0

Cosa suggerisci di fare per il terzo esempio (con "applymap")? –

5

d'accordo con Paul sull'uso 'loc'.

Per il vostro caso applyMap si dovrebbe essere in grado di fare questo:

cols = ['col1', 'col2', 'col3'] 
df.loc[:, cols] = df[cols].applymap(some_function) 
+3

Questo dà lo stesso avviso. Ma questo non lo fa: df.loc [:, cols] = df.loc [:, cols] .applymap (some_function) –

+0

Interessante. Sto usando pandas 0.15.0 ma Python 2.7.5 quindi non ho testato con il tuo ambiente. Il mio suggerimento non lancia l'avvertimento per me. Buono a sapersi che il tuo ultimo tentativo ha funzionato – koelemay