Pandas SettingWithCopyWarning [duplicate]
Asked Answered
B

2

25

Python 3.4 and Pandas 0.15.0

df is a dataframe and col1 is a column. With the code below, I'm checking for the presence of the value 10 and replacing such values with 1000.

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

Here's another example. This time, I'm changing values in col2 based on index.

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

Both these produce the warning below:

-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

Finally,

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

This produces a similar warning, with an added suggestion:

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

I'm not sure I understand the discussion pointed to in the warnings. What would be a better way to write these three lines of code?

Note that the operations worked.

Belsky answered 3/11, 2014 at 22:23 Comment(0)
S
39

The issue here is that: df.col1[df.col1 == 10] returns a copy.

So I would say:

row_index = df.col1 == 10
# then with the form .loc[row_indexer,col_indexer]
df.loc[row_index, 'col1'] = 100
Stocks answered 3/11, 2014 at 22:37 Comment(4)
Thanks. Should be df.loc[row_index, 'col1'] = 100, right?Belsky
@asif.m are are of course 100% correct. I'll fix itStocks
What do you suggest I do for the third example (with "applymap")?Belsky
@asif.m I need a runnable example that uses applymap to assist further.Stocks
K
5

Agreed with Paul about 'loc' usage.

For your applymap case you should be able to do this:

cols = ['col1', 'col2', 'col3']
df.loc[:, cols] = df[cols].applymap(some_function)
Kayo answered 4/11, 2014 at 16:19 Comment(3)
That gives the same warning. But this one doesn't: df.loc[:, cols] = df.loc[:, cols].applymap(some_function)Belsky
Interesting. I'm using pandas 0.15.0 but Python 2.7.5 so didn't test with your environment. My suggestion does not throw the warning for me. Good to know that your latter attempt workedKayo
I'm getting the copy warning even though I'm using .loc: col_pct = ['Cash', 'Funds'] ui_df.loc[:, col_pct] = ui_df.loc[:, col_pct].applymap('{0:.2f}%'.format)Nanananak

© 2022 - 2024 — McMap. All rights reserved.