问题
I have a dataframe, I want to change only those values of a column where another column fulfills a certain condition. I'm trying to do this with iloc
at the moment and it either does not work or I'm getting that annoying warning:
A value is trying to be set on a copy of a slice from a DataFrame
Example:
import pandas as pd
DF = pd.DataFrame({'A':[1,1,2,1,2,2,1,2,1],'B':['a','a','b','c','x','t','i','x','b']})
Doing one of those
DF['B'].iloc[:][DF['A'] == 1] = 'X'
DF.iloc[:]['B'][DF['A'] == 1] = 'Y'
works, but leads to the warning above.
This one also gives a warning, but does not work:
DF.iloc[:][DF['A'] == 1]['B'] = 'Z'
I'm really confused about how to do boolean indexing using loc
, iloc
, and ix
right, that is, how to provide row index, column index, AND boolean index in the right order and with the correct syntax.
Can someone clear this up for me?
回答1:
You are chaining you're selectors, leading to the warning. Consolidate the selection into one.
Use loc
instead
DF.loc[DF['A'] == 1, 'B'] = 'X'
DF
回答2:
Use ix:
import pandas as pd
DF = pd.DataFrame({'A':[1,1,2,1,2,2,1,2,1],'B':['a','a','b','c','x','t','i','x','b']})
DF.ix[DF['A'] == 1, 'B'] = 'X'
print (DF)
0 1 X
1 1 X
2 2 b
3 1 X
4 2 x
5 2 t
6 1 X
7 2 x
8 1 X
Another solution with mask:
DF.B = DF.B.mask(DF['A'] == 1, 'X')
print (DF)
A B
0 1 X
1 1 X
2 2 b
3 1 X
4 2 x
5 2 t
6 1 X
7 2 x
8 1 X
Nice article about SettingWithCopy by Tom Augspurger.
来源:https://stackoverflow.com/questions/39612300/pandas-change-values-chosen-by-boolean-indexing-in-a-column-without-getting-a-w