I have a dataframe:
jb = pd.DataFrame([ ['No', 75, 2.0], ['Blofeld', 140, 1.9], ['Chiffre', 114, 1.7] ],
index=['b1', 'b5', 'b21'], columns=['Name', 'Weight', 'Height'])
Then if I do chained assignment as below, it won't change the original value in jb. And it will also trigger SettingWithCopyWarning .
jb[jb.Weight==75]['Height'] = 9
But if I switch the order of chained assignment, it will then change the original value in jb, but still also trigger SettingWithCopyWarning .
jb['Height'][jb.Weight==75] = 9
So the second code is still producing a copy but why it ends up modifying the original jb?
You should not try to do what you call chained assignments. Pandas documentation states that it is unspecified whether you get a view (and change the original value) or a copy (and do not). AFAIK, it depends on implementation details and on the internals on Pandas optimization code.
That being said the observed behavious is no surprise. In a Pandas DataFrame, data is stored in numpy arrays by columns. So when you access first by column (your second code), Pandas can easily give you access to the underlying numpy array as a Series. But when you access first by row (your first code) Pandas has to build a new Series, and only give you a copy of the original data.
Nevertheless, the only reliable way is to use
loc: