SettingwithCopyWarning: 如何修复这个Pandas当中出现的warning
首先这个告警是什么含义呢?
我们首先来看这两个图:

上图左边的df2 是df1的视图,而右边的则是df1的复制,当你尝试改变例如df1的时候,可能改变的仅仅是df1当中的一个复制(df2),真正的df1没有被改变。

例如我们有这样一组数据:

我们想把其中bidder列当中为值为parakeet2004的,bidderate的列 设为100,那么可能我们会这么做。
data[data.bidder == 'parakeet2004']['bidderrate'] = 100
但是我们会得到这样的warning,为什么呢?
这是因为这个操作实际分成了两步,那就是下面这两步。
data[data.bidder == 'parakeet2004']['bidderrate'] = 100
第一步实际会生成另一个dataframe,包含bidder列当中为值为parakeet2004的所有行。
第二步实际是在这个复制的dataframe做一个赋值操作,并没有在原始的data这个dataframe当中操作。
如何解决呢?
就是将两步合成一步,在data的view视图当中去操作。
data.loc[data.bidder == 'parakeet2004', 'bidderrate'] = 100
此外还有一种更加隐蔽的情况,出现在你想获得一份data的部分复制品,然后对这个复制品进行修改。
winners = data.loc[data.bid == data.price] winners.loc[304, 'bidder'] = 'therealname' /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pandas/core/indexing.py:517: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.Try using .loc[row_indexer,col_indexer] = value insteadSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy self.obj[item] = s
我们已经使用loc了,为什么还会出现这个告警。实际在第一步当中你获得的是data的view视图,所以后面你实际修改的是还是data的304行,‘bidder’列当你想获得一个复制的dataframe时,建议还是使用copy(),显式地告诉pandas 你想做什么。
解决方法:
winners = data.loc[data.bid == data.price].copy() winners.loc[304, 'bidder'] = 'therealname'
最后你也可以关闭这个waning,虽然我觉得这样做可能导致意想不到的结果。
'raise'— to raise an exception instead of a warning.'warn'— to generate a warning (default).None— to switch off the warning entirely.
pd.set_option('mode.chained_assignment', None)
参考文档:

浙公网安备 33010602011771号