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.

0

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Should be df.loc[row_index, 'col1'] = 100, right?
@asif.m are are of course 100% correct. I'll fix it
What do you suggest I do for the third example (with "applymap")?
@asif.m I need a runnable example that uses applymap to assist further.
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)

3 Comments

That gives the same warning. But this one doesn't: df.loc[:, cols] = df.loc[:, cols].applymap(some_function)
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 worked
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)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.