4

Having a DataFrame with one column volume_:

up = df['volume_'].rolling(30).max()
df['up'] = up

Leads to the classic sempiternal SettingWithCopyWarning warning about "a value trying to be set on a copy of a slice from a dataframe". This well-known warning suggests:

Try using .loc[row_indexer,col_indexer] = value instead

Alright, let's do it as they say!

up = df['volume_'].rolling(30).max()
df.loc[:, 'up'] = up

And now, instead of one SettingWithCopyWarning warning, I get two!

site-packages/pandas/core/indexing.py:845: 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

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[key] = _infer_fill_value(value)
site-packages/pandas/core/indexing.py:1048: 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

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[item_labels[indexer[info_axis]]] = value

In essence, Pandas is complaining that I use df.loc[:, 'up'] = ... and suggests me to use df.loc[:, 'up'] = ... instead...

What would be the proper, Pandas-compliant way to achieve this purpose?

Jivan
  • 21,522
  • 15
  • 80
  • 131

1 Answers1

2

I got it.

What I didn't say (and thought wasn't relevant) in the question is that I was building df out of slicing an existing DataFrame:

df = other_df[['volume_']]

When I do this instead:

df = other_df[['volume_']].copy()

Then everything falls back in order.

Still, my takeaway is that the warning message could probably benefit from being worded a bit more clearly, to say the least.

Jivan
  • 21,522
  • 15
  • 80
  • 131