Reputation: 147
There seems to be a lot of confusion around the .loc and SettingWithCopyWarning. In my case I could not find a solution to this situation from existing questions.
Currently I have a DF which I would like to filter with slices and then set values to these slices which propagate to the original. So I do not want a copy, I want the view which I modify.
Currently it works with this:
A0.loc[(A0['Pääkategoria'].isnull()) & (A0.Määrä < 0) & (A0.SaajaMaksaja.str.contains('|'.join(catfilter))), 'Pääkategoria'] = cat1
This will get quite complicated when there are lot of filters to be fullfilled. Is it possible to get views "incrementally" which I work on and then the set values to the view are propagated to the original DF A0
?
Now I have the following which causes: SettingWithCopyWarning
A1 = A0.loc[(A0['Pääkategoria'].isnull() & (A0.Määrä < 0))]
A1.loc[A1.SaajaMaksaja.str.contains('|'.join(catfilter)), 'Pääkategoria'] = cat1
So it seems that the A1
is only a copy, not a slice. Slicing multiple times would allow me to do slices for different situations (> 0 for example)
Upvotes: 2
Views: 771
Reputation: 46
try this one after importing pandas (as pd)
pd.options.mode.chained_assignment = None
just try
Upvotes: 0
Reputation: 164683
In my opinion, a much more readable solution which should not cause SettingWithCopyWarning
is to calculate your partial mask as a separate step.
Then use the &
operator once within pd.DataFrame.loc
:
mask = A0['Pääkategoria'].isnull() & (A0.Määrä < 0)
A0.loc[mask & A1.SaajaMaksaja.str.contains('|'.join(catfilter)), 'Pääkategoria'] = cat1
Chaining loc
indexers, as you noticed, is liable to raise SettingWithCopyWarning
. But this chaining is not necessary to calculate the intersection of Boolean series.
Upvotes: 1