2014-11-03 19 views
19

Python 3.4 i Pandy 0.15.0Ustawienie PandSWithCopyWarning

df jest ramką danych, a col1 jest kolumną. Za pomocą poniższego kodu sprawdzam obecność wartości 10 i zastępuję te wartości wartością 1000.

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

Oto kolejny przykład. Tym razem zmieniam wartości w col2 na podstawie indeksu.

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

Oba te produkują poniżej ostrzeżenie:

-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 

Wreszcie

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

To daje podobne ostrzeżenie, z dodatkiem sugestia:

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

I nie jestem pewien, czy rozumiem płytę ussion wskazał w ostrzeżeniach. Jaki byłby lepszy sposób napisania tych trzech linii kodu?

Należy zauważyć, że operacje zadziałały.

Odpowiedz

38

Problem polega na tym, że: df.col1[df.col1 == 10] zwraca kopię.

Więc powiedziałbym:

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

Dzięki. Powinien być df.loc [row_index, 'col1'] = 100, prawda? –

+1

@ asif.m są oczywiście w 100% poprawne. Naprawię to. –

+0

Co proponujesz zrobić dla trzeciego przykładu (z "applymap")? –

5

zgodził się z Pawłem na temat wykorzystania 'loc'.

Twoim przypadku applymap powinieneś być w stanie to zrobić:

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

To daje takie samo ostrzeżenie. Ale ten nie ma: df.loc [:, cols] = df.loc [:, cols] .applymap (some_function) –

+0

Interesujące. Używam pand w wersji 0.15.0, ale Python 2.7.5, więc nie testowałem w twoim środowisku. Moja sugestia nie rzuca mi ostrzeżenia. Dobrze wiedzieć, że twoja ostatnia próba zadziałała – koelemay