The code issuing the SettingWithCopyWarning can be fully replicated. See the edit below for more strange behaviour wrt consistency of getting the warning. FYI, this is not a duplicate of these 3 questions:
- python astype(str) gives SettingWithCopyWarning and requests I use loc
- "At some point prior to the assignment, you created df in such a way that it became a view into another dataframe."
- Mine can be created from scratch with the code below, and not from another df.
- Python - Getting “SettingWithCopyWarning” despite using df.loc
- "Create the 2nd dataframe with the following code..."
- I'm only creating and using one DataFrame.
- How to deal with SettingWithCopyWarning in Pandas
- I am using
.locbut I'm assigning to a column slice; isn't covered in the answers there.
- I am using
The code:
df = pd.DataFrame({
'Fruits': ['apple', 'orange', 'banana', 'pineapple', 'watermelon'],
'Volume 1': [10, 20, 30, 700, 800],
'Volume 2': [100, 200, 300, 7000, 8000],
'Volume 3': [1, 2, 3, 70, 8],
'Volume 4': [9, 8, 7, 6, 5],
'Other': [-1, -2, -3, -4, -5]
})
df.loc[:, 'Volume 2':'Volume 4'] = df.loc[:, 'Volume 2':'Volume 4'].shift(1)
df = df.dropna()
# All okay so far, no warnings
# This next line issues a `SettingWithCopyWarning`:
df.loc[:, 'Volume 2':'Volume 4'] = df.loc[:, 'Volume 2':'Volume 4'].astype(int) # warning
# and if I execute this line again, it now issues SWC warning:
df.loc[:, 'Volume 2':'Volume 4'] = df.loc[:, 'Volume 2':'Volume 4'].shift(1) # warning
# And any following operation now issues the SWCW:
df['A'] = 'foo' # new column
df['Fruits'] = 'a fruit' # existing column
I can get rid of the warning by doing either one of:
df = df.dropna()
# or
df = df.copy()
If I then redo different versions of the previous astype() step, there's no warning:
df.loc[:, 'Volume 2':'Volume 4'] = df.loc[:, 'Volume 2':'Volume 4'].astype(float) # no warning
df.loc[:, 'Volume 2':'Volume 4'] = df.loc[:, 'Volume 2':'Volume 4'].astype(int) # no warning
If the first astype() step issues SettingWithCopyWarning, why didn't these? Shouldn't it be consistent? I'm on pandas version '1.2.2'.
Btw, even if I could explicitly list all the columns I was converting in the first astype() step, in these different ways, they also issue SWC warnings:
df.loc[:, 'Volume 2':'Volume 4'] = df[['Volume 2', 'Volume 3', 'Volume 4']].astype(int)
df[['Volume 2', 'Volume 3', 'Volume 4']] = df.loc[:, 'Volume 2':'Volume 4'].astype(int)
df[['Volume 2', 'Volume 3', 'Volume 4']] = df[['Volume 2', 'Volume 3', 'Volume 4']].astype(int)
Edit/Update: In JupyterLab and IPython, if dropna() is executed in the same cell as the shift() step, then no warning is issued. So this might be kernel-related. Here's a pastebin link to the IPython code.