Suppose I have the following DataFrame:
In [1]: df
Out[1]:
apple banana cherry
0 0 3 good
1 1 4 bad
2 2 5 good
It's because df[['apple', 'banana']][df.cherry == 'bad'] = np.nan
assigning to the copy of DataFrame. Try this:
df.ix[df.cherry == 'bad', ['apple', 'banana']] = np.nan
You should use loc and do this without chaining:
In [11]: df.loc[df.cherry == 'bad', ['apple', 'banana']] = np.nan
In [12]: df
Out[12]:
apple banana cherry
0 0 3 good
1 NaN NaN bad
2 2 5 good
See the docs on returning a view vs a copy, if you chain the assignment is made to the copy (and thrown away) but if you do it in one loc then pandas cleverly realises you want to assign to the original.