微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 了解Pandas SettingWithCopyWarning

我有以下代码,但不太明白为什么它会抛出警告.我已经阅读了documentation,但仍然无法理解为什么这种用法会导致警告.任何见解将不胜感激.

>>> df = pandas.DataFrame({'a': [1,2,3,4,5,6,7], 'b': [11,22,33,44,55,66,77]})
>>> reduced_df = df[df['a'] > 3]
>>> reduced_df
   a   b
3  4  44
4  5  55
5  6  66
6  7  77
>>> reduced_df['a'] /= 3

Warning (from warnings module):
   File "__main__", line 1
SettingWithcopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
>>> reduced_df
          a   b
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77

解决方法:

这里的警告是告诉你,尽管出现了你的reduced_df并不是对你的df片段的引用,但实际上是副本.这与普通语义不同,人们会期望这会导致引用,并且对该引用的修改将影响引用和原始对象(当然对于可变对象):

In [14]:

foo = [0]
bar = foo
bar.append(1)
print(foo,bar)
[0, 1] [0, 1]

因此,如果您想修改df的特定切片,那么您应该执行警告建议:

In [18]:

df.loc[df['a']>3,'a'] =df['a']/3
df
Out[18]:
          a   b
0  1.000000  11
1  2.000000  22
2  3.000000  33
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77

或者制作一个显式的深拷贝调用copy()修改副本而不产生任何警告:

In [20]:

reduced_df = df[df['a'] > 3].copy()
reduced_df['a'] /=3
reduced_df
Out[20]:
          a   b
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77

In [21]:
# orig df is unmodified
df
Out[21]:
   a   b
0  1  11
1  2  22
2  3  33
3  4  44
4  5  55
5  6  66
6  7  77

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐