当一行DataFrame是字符串时,SettingWithCopyWarning

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当一行DataFrame是字符串时,SettingWithCopyWarning相关的知识,希望对你有一定的参考价值。

我得到一个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中是数字。难道我做错了什么?是否有不同的(首选?)方式来做到这一点?该警告不应该始终如一地应用吗?

答案

你两次都做错了。您在两种情况之一中收到警告的事实无关紧要。你永远不应该使用链式索引。事实上,它是文档中的explicitly discouraged

相反,你可以使用pd.DataFrame.loc

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

在这种方法中,我看到没有警告或错误。为了避免昂贵的布尔索引,更好的想法是使用np.maximum

rain['value'] = np.maximum(0, rain['value'])
另一答案

在这个问题的情况下:

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

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

为什么一个工作而不是另一个工作:

来自Indexing and Selecting Data的pandas文档 - 部分评估顺序事项

链式分配也可以在混合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

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

以上是关于当一行DataFrame是字符串时,SettingWithCopyWarning的主要内容,如果未能解决你的问题,请参考以下文章

当数据框既是 int 又是字符串时,在 Dataframe 中查找行?

当字符串列内容长于已经存在的内容时,HDFStore.append(string, DataFrame) 失败

将 pandas DataFrame 的每一行转换为单独的 Json 字符串

pandas使用set_index函数将dataframe中的特定数据列转化为索引列(setting a new index of a dataframe)

pandas使用iloc函数将dataframe所有的数值重置为0或者其他固定值(setting all values in dataframe to zero or other value)

在 pyspark 的 StructStreaming 中;如何将 DataFrame 中的每一行(json 格式的字符串)转换为多列