首先,我尝试编写一些类似于以下代码的代码:
import numpy as np
import pandas as pd
np.random.seed(2016)
train = pd.DataFrame(np.random.choice([np.nan, 1, 2], size=(10, 3)),
columns=['Age', 'SibSp', 'Parch'])
complete = train.dropna()
complete['AgeGt15'] = complete['Age'] > 15
获取SettingWithCopyWarning之后,我尝试使用.loc:
complete.loc[:, 'AgeGt15'] = complete['Age'] > 15
complete.loc[:, 'WithFamily'] = complete['SibSp'] + complete['Parch'] > 0
但是,我仍然收到相同的警告。是什么赋予了?
最佳答案
注意:自 Pandas 0.24版起,不建议使用is_copy
,并将在以后的版本中将其删除。当存在私有(private)属性_is_copy
时,下划线表示该属性不是公共(public)API的一部分,因此不应依赖于此属性。因此,展望 future ,使SettingWithCopyWarning
静音的唯一正确方法似乎是在全局范围内这样做:
pd.options.mode.chained_assignment = None
当执行
complete = train.dropna()
时,dropna
可能会返回一个副本,因此出于谨慎考虑,Pandas将
complete.is_copy
设置为Truthy值:
In [220]: complete.is_copy
Out[220]: <weakref at 0x7f7f0b295b38; to 'DataFrame' at 0x7f7eee6fe668>
这样,当执行
complete['AgeGt15'] = complete['Age'] > 15
时,Pandas便会警告您,您可能正在修改对train
无效的副本。对于初学者来说,这可能是一个有用的警告。在您的情况下,您似乎无意通过修改train
间接修改complete
。因此,警告对您而言只是毫无意义的烦恼。您可以通过以下方式使警告静音:
complete.is_copy = False # deprecated as of version 0.24
这比制作实际副本要快,并且将芽中的
SettingWithCopyWarning
压缩(在where _check_setitem_copy
is called点):def _check_setitem_copy(self, stacklevel=4, t='setting', force=False):
if force or self.is_copy:
...
如果您真的有信心知道自己在做什么,则可以使用以下命令全局关闭
SettingWithCopyWarning
pd.options.mode.chained_assignment = None # None|'warn'|'raise'
使警告静音的另一种方法是制作新副本:
complete = complete.copy()
但是,如果DataFrame很大,您可能不想这样做,因为复制
可能会花费大量的时间和内存,这是
如果您知道
complete
已经是一个副本,则完全没有意义(为了消除警告而已)。关于python - 即使使用.loc后, Pandas 仍会收到SettingWithCopyWarning,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38809796/