如果使用下面的代码1,则会出现以下错误:
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
如果我使用代码2,却没有得到它。
两个代码都应创建一个副本,为什么打印功能会更改此副本?
代码1
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
df
def f(df_par):
df_par.iloc[0, 0] = 8
mask = df.iloc[:, 0] > 1
df = df.loc[mask,:]
f(df)
代码2
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
print(df)
def f(df_par):
df_par.iloc[0, 0] = 8
mask = df.iloc[:, 0] > 1
df = df.loc[mask,:]
f(df)
答案 0 :(得分:0)
首先,这是警告而不是错误。但是,它在那里是有原因的,不应忽略!
如here所述,发生此警告的原因是,很难预测您的一行是复制数据帧还是仅查看数据帧(深层副本还是浅层副本)。
这是有问题的行:
df = df.loc[mask,:]
您的打印操作实际上并未更改任何内容。运行打印后,此行仍可能正在创建副本。在这种情况下,我们知道肯定是在创建一个副本,由于发出警告,我们知道该副本,但是并非总是如此,因此发出警告。
区别在于检测到此问题的代码。要检测到此问题,必须发生某些事情,而在调用print()之后才发生。
要解决此问题,只需将行更改为此,以确保您和您的代码知道您正在创建副本:
df = (df.loc[mask,:]).copy()