在pandas中设置切片的正确方法是什么?

95

我有一个名为data的pandas数据框,其中包含列["name", 'A', 'B']。

我的目标是(并且已经成功实现):

d2 = data[data['name'] == 'fred'] #This gives me multiple rows
d2['A'] = 0

这将把fred行的A列设为0。 我还做了以下事情:

indexes = d2.index
data['A'][indexes] = 0

然而,两者都给我同样的警告:

/Users/brianp/work/cyan/venv/lib/python2.7/site-packages/pandas/core/indexing.py:128: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

pandas希望我用什么方式来做这件事?

1个回答

148

这是 pandas 经常发出的警告。它意味着您正在写入复制切片,而不是原始数据,因此可能不适用于原始列,因为会导致混淆的链式赋值。请阅读此博客。它对 SettingWithCopyWarning 进行了详细讨论。在您的情况下,我认为您可以尝试

data.loc[data['name'] == 'fred', 'A'] = 0

3
我正要发布同样的内容。一个逻辑简洁的“一行话”比冗长的代码更好。 - tnknepp
18
很多人说这是正确的方法,我也采用这种方法。但有时候我仍然会收到警告,说我正在对副本设置值,并建议我使用 .loc,尽管我已经在使用它了。有人遇到过同样的情况吗? - Calvin Ku
11
@CalvinKu,是的!我在按照它要求我的做时也收到了同样的警告!在我看来,这是一种模糊的行为,应该被视为一个错误,但Pandas团队已经厌倦了听到这个问题,所以我对他们会解决它没有太多信心...真是遗憾...特别是来自R。 - Bryan Goggin
5
有趣的是,有时我会得到这个警告,无论我如何重构它都无法消除。但是,当我一段时间后再次运行相同的代码时,警告就不再出现了。我猜测 pandas 的这部分实现并不是非常健壮,所以偶尔会出现这样的误报。但令我困扰的是,似乎并不是所有人都遇到这个问题,因此他们确信是你的代码有问题...哈哈 - Calvin Ku
3
@CalvinKu,当你要分配给的数据框是另一个数据框的视图时会出现这种情况。例如考虑以下代码:{a = pd.DataFrame({'x':[1],'y':[1]}); b = a[['x']]; b.loc[:,'x'] = 0}。在这里,你会收到一个"settingwithcopy"警告,提醒你已经改变了b的值,但没有改变a的值。 - Viktoriya Malyasova
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接