尝试在NetC DF中创建一个新列,但我得到了警告
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
C:Anacondalibsite-packagesipykernel__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
什么是在较新版本的熊猫中创建字段以避免警告的正确方法?
pd.__version__
Out[45]:
u'0.19.2+0.g825876c.dirty'
您的示例不完整,因为它没有显示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
正如它在错误中所说的那样,尝试使用 .loc[row_indexer,col_indexer]
创建新列。
netc.loc[:,"DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM.
注释
由熊猫索引文档您的代码应起作用。
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
被翻译成
netc.__setitem__('DeltaAMPP', netc.LOAD_AM - netc.VPP12_AM)
应该具有可预测的行为。SettingWithCopyWarning
只能在链式分配过程中警告用户意外行为(这不是您在做的事情)。但是,如文档中所述,
有时会在没有明显的链接索引进行时会出现
SettingWithCopy
警告。这些是SettingWithCopy
旨在捕获的错误!Pandas可能试图警告您您已经做到了:
然后,文档继续举例说明即使没有预期,何时可能会出现该错误。所以我无法说出为什么没有更多上下文会发生这种情况。
i具有 SettingWithCopyWarning
issue,当将数据分配给数据框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
顺便说一句:建议阅读有关此问题的文档(警告中的链接)
您需要reset_index何时创建列,尤其是当您对特定值进行过滤时...然后您不需要使用.loc [row_indexer,col_indexer]
netc.reset_index(drop=True, inplace=True)
netc["DeltaAMPP"] = netc.LOAD_AM - netc.VPP12_AM
然后它应该有效:)
正如其他答案中指出的那样,您很有可能对数据进行了一些过滤,否则此警告不应弹出(因为您的步骤正确)。/p>
假设您已经进行了一些过滤,则可以尝试执行以下步骤:
netc_copied = netc.copy()
netc.loc[:, "DeltaAMPP"] = netc_copied["LOAD_AM"] - netc_copied["VPP12_AM"]
请注意,我在原始数据框架中添加了一个新列。您也可以在复制的数据框架中执行此操作。
一个更简单的解决方案是仅使用'sigtion':
netc = netc.assign(DeltaAMPP=netc_copied['LOAD_AM']-netc_copied['VPP12_AM'])
另外您也可以使用eval
:
netc.eval('DeltaAMPP = LOAD_AM - VPP12_AM', inplace = True)
由于inplace=True
您无需将其分配给netc
。
即使使用.loc或.iloc进行切片,您仍然会出现错误,您要做的就是切片后重置索引
df.reset_index()