I'm trying to create a moving average column for my data called 'mv_avg'. I'm getting a SettingWithCopyWarning that I have been unable to fix. I could suppress the warning, but I cannot figure out where in my code I am creating a copy, and I want to utilize best practices. I've created a generalizable example below to illustrate the problem.
data = {'category' : ['a', 'a', 'a', 'b', 'b', 'b'], 'value' : [1,2,3,4,5,6]}
df = pd.DataFrame(data)
df_a = df.loc[df['category'] == 'a']
df_a['mv_avg'] = df_a['value'].rolling(window=2).mean()
This returns:
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
I've also tried the more verbose version:
df_a.loc[: , 'mv_avg'] = df_a.loc[:,'value'].rolling(window=2).mean()
but I get the same error. What is the best way to accomplish this without the warning?
Here are three options
Ignore/filter the warning; in this case it is spurious as you are deliberately assigning to a filtered DataFrame.
If you are done with
df
, you coulddel
it, which will prevent the warning, becausedf_a
will no longer hold a reference todf
.Take a copy as in the other answer
you can create a copy using .copy()
or you can use an indexer such has :