当一行DataFrame是字符串时,SettingWithCopyWarning

时间:2015-09-23 14:38:01

标签: python pandas dataframe indexing

我获得了以下代码的SettingWithCopyWarning:

rain = DataFrame({'data':['1','2','3','4'],
                  'value':[1,-1,1,1]})
rain.value[rain.value < 0] = 0

虽然我没有收到

的警告
rain = DataFrame({'data':[1,2,3,4],
              'value':[1,-1,1,1]})
rain.value[rain.value < 0] = 0

唯一的区别是'data'列是第一个DataFrame中的字符串,第二个DataFrame中是数字。难道我做错了什么?是否有不同的(首选?)方式来做到这一点?该警告不应该始终如一地应用吗?

2 个答案:

答案 0 :(得分:1)

对于此问题:

rain.value[rain.value < 0] = 0  # doesn't work

rain.loc[rain.value < 0] = 0  # works

为什么一个起作用而另一个不起作用:

摘自Indexing and Selecting Data的熊猫文档-评估部分的重要事项

在混合dtype框架中的设置中,也可以出现连锁分配。

注意:这些设置规则适用于所有.loc / .iloc。

这是正确的访问方法:

In [345]: dfc = pd.DataFrame({'A':['aaa','bbb','ccc'],'B':[1,2,3]})

In [346]: dfc.loc[0,'A'] = 11

In [347]: dfc
Out[347]: 
     A  B
0   11  1
1  bbb  2
2  ccc  3

这有时可以起作用,但不能保证一定可以,因此应避免:

In [348]: dfc = dfc.copy()

In [349]: dfc['A'][0] = 111

In [350]: dfc
Out[350]: 
     A  B
0  111  1
1  bbb  2
2  ccc  3

这根本不起作用,因此应避免:

>>> pd.set_option('mode.chained_assignment','raise')
>>> dfc.loc[0]['A'] = 1111
Traceback (most recent call last)
     ...
SettingWithCopyException:
     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

警告链接的作业警告/异常的目的是通知用户可能无效的作业。可能存在误报;意外报告链接分配的情况。

答案 1 :(得分:1)

您在两次场合都做错了。您在两种情况之一中收到警告的事实并不重要。您应该从不使用链接索引。实际上,它们是文档中的explicitly discouraged

您可以使用pd.DataFrame.loc

rain.loc[rain.value < 0, 'value'] = 0

在这种情况下,我都看不到任何警告或错误。为了避免昂贵的布尔索引,一个更好的主意是使用np.maximum

rain['value'] = np.maximum(0, rain['value'])