尝试在netc df中创建一个新列,但我收到了警告
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
C:\Anaconda\lib\site-packages\ipykernel\__main__.py:1: 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 instead
在新版本的Pandas中创建字段的正确方法是什么,以避免收到警告?
pd.__version__
Out[45]:
u'0.19.2+0.g825876c.dirty'
答案 0 :(得分:15)
正如错误中所述,请尝试使用.loc[row_indexer,col_indexer]
创建新列。
netc.loc[:,"DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM.
通过Pandas Indexing Docs你的代码应该可行。
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
被翻译为
netc.__setitem__('DeltaAMPP', netc.LOAD_AM - netc.VPP12_AM)
哪个应该具有可预测的行为。 SettingWithCopyWarning
仅用于警告用户在链接分配期间出现意外行为(这不是您正在做的事情)。但是,如文档中所述,
有时候,如果没有明显的链式索引,会出现
SettingWithCopy
警告。这些是SettingWithCopy
旨在捕获的错误!熊猫可能会试图警告你,你已经这样做了:
然后,文档会继续举例说明即使不期望错误,也可能会出现错误。因此,我无法在没有更多背景的情况下告诉为什么会发生这种情况。
答案 1 :(得分:1)
创建列时,您需要reset_index,特别是如果您已过滤特定值...则不需要使用.loc [row_indexer,col_indexer]
netc.reset_index(drop=True, inplace=True)
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
然后它应该可以工作了:)
答案 2 :(得分:0)
您的示例不完整,因为它没有显示netc
的来源。 netc本身很可能是切片的产物,因此Pandas无法保证它不是视图或副本。
例如,如果您正在执行此操作:
netc = netb[netb["DeltaAMPP"] == 0]
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
然后,熊猫不会知道netc
是视图还是副本。如果是单线的,实际上就是这样:
netb[netb["DeltaAMPP"] == 0]["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
您可以在其中更清楚地看到双索引。
如果要将netc
与netb
分开,一种可能的解决方法可能是强制在第一行中进行复制(loc
是确保我们不进行复制两次),例如:
netc = netb.loc[netb["DeltaAMPP"] == 0].copy()
另一方面,如果您想用新列修改netb
,则可以执行以下操作:
netb.loc[netb["DeltaAMPP"] == 0, "DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
答案 3 :(得分:0)
在将数据分配给通过索引构建的 DataFrame SettingWithCopyWarning
时,我遇到了 df
问题。
两个命令
df['new_column'] = something
df.loc[:, 'new_column'] = something
没有警告就无法工作。
复制 df
(DataFrame.copy()) 后一切正常。
在下面的代码中,比较 df0 = df_test[df_test['a']>3]
和 df1 = df_test[df_test['a']>3].copy()
。
对于 df0
,两个赋值都会抛出警告。对于 df1
,两者都可以正常工作。
>>> df_test
a b c d e
0 0.0 1.0 2.0 3.0 0
1 4.0 5.0 6.0 7.0 1
2 8.0 9.0 10.0 11.0 2
3 12.0 13.0 14.0 15.0 3
4 16.0 17.0 18.0 19.0 4
>>> df0 = df_test[df_test['a']>3]
>>> df1 = df_test[df_test['a']>3].copy()
>>> df0['e'] = np.arange(4)
__main__:1: 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 instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
>>> df1['e'] = np.arange(4)
>>> df0.loc[2, 'a'] = 77
/opt/anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:1719: 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 instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
self._setitem_single_column(loc, value, pi)
>>> df1.loc[2, 'a'] = 77
>>> df0
a b c d e
1 4.0 5.0 6.0 7.0 0
2 77.0 9.0 10.0 11.0 1
3 12.0 13.0 14.0 15.0 2
4 16.0 17.0 18.0 19.0 3
>>> df1
a b c d e
1 4.0 5.0 6.0 7.0 0
2 77.0 9.0 10.0 11.0 1
3 12.0 13.0 14.0 15.0 2
4 16.0 17.0 18.0 19.0 3
顺便说一句:建议阅读有关此问题的文档(警告中的链接)