Pandas 中 SettingwithCopyWarning

在用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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值