在用pandas时出现这个警告(SettingWithCopyWarning) 表示你的操作可能没有按预期运行,你应该检查结果以确保没有出错。
一般很容易忽略警告,这不是良好的实践,SettingWithCopyWarning 不应该被忽略。
原文:https://www.dataquest.io/blog/settingwithcopywarning/
翻译:https://www.jianshu.com/p/72274ccb647a
产生警告的原因:
1.当 Pandas 检测链式赋值(Chained assignment)时会生成警告。
生成警告是因为我们将两个索引操作链接在一起,我们直接使用了两次方括号。
data[data.bidder == 'parakeet2004']['bidderrate'] = 100
但如果我们使用其他访问方法,例如 .bidderrate、.loc[]、.iloc[]、.ix[],也是如此,我们的链式操作是:
data[data.bidder == 'parakeet2004']['bidderrate'] = 100
这两个链式操作一个接一个地独立执行。第一次是访问操作(get),返回一个 DataFrame,其中包含所有 bidder 等于 'parakeet2004' 的行。第二个是赋值操作(set),是在这个新的 DataFrame 上运行的,我们压根没有在原始 DataFrame 上运行。
这个解决方案很简单:使用 loc 将链式操作组合到一个操作中,以便 Pandas 可以确保 set 的是原始 DataFrame。Pandas 会始终确保下面这样的非链式 set 操作起作用。
# 设置新值
data.loc[data.bidder == 'parakeet2004', 'bidderrate'] = 100
# 检查结果
data[data.bidder == 'parakeet2004']['bidderrate']
2.隐蔽的链式操作(Hidden chaining)
链式索引可能跨越两行代码发生,也可能在一行代码内发生。因为 winners 是作为 get 操作的输出创建的(data.loc[data.bid == data.price]),它可能是原始 DataFrame 的副本,也可能不是,但除非我们检查,否则我们不能了解到。当我们对 winners 进行索引时,我们实际上使用的是链式索引。
这意味着当我们尝试修改 winners 时,我们可能也修改了 data。
在实际的代码中,这些行可能会跨越很大的距离,因此追踪问题可能会更困难,但情况是与示例类似的。
为了防止这种情况下的警告,解决方案是在创建新 DataFrame 时明确告知 Pandas 制作一个副本:
winners = data.loc[data.bid == data.price].copy()
winners.loc[304, 'bidder'] = 'therealname'
print(winners.loc[304, 'bidder'])
print(data.loc[304, 'bidder'])
therealname
nan
本文解析了在使用Pandas时常见的SettingWithCopyWarning警告产生的原因,包括链式赋值及隐蔽的链式操作,并提供了相应的解决办法。
1501

被折叠的 条评论
为什么被折叠?



