首先,我尝试编写一些类似于以下代码的代码:
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
但是,我仍然收到相同的警告。是什么赋予了?
注意:自大熊猫0.24版本起,is_copy已弃用该版本,并将在以后的版本中将其删除。当private属性_is_copy存在时,下划线表示该属性不是公共API的一部分,因此不应依赖于此属性。因此,展望未来,沉默的唯一正确方法似乎SettingWithCopyWarning是在全球范围内这样做:
is_copy
_is_copy
SettingWithCopyWarning
pd.options.mode.chained_assignment = None
当complete = train.dropna()执行时,dropna可能会返回一个副本,因此出于谨慎考虑,Pandas设置complete.is_copy为Truthy值:
complete = train.dropna()
dropna
complete.is_copy
In [220]: complete.is_copy Out[220]: <weakref at 0x7f7f0b295b38; to 'DataFrame' at 0x7f7eee6fe668>
这样一来,Pandascomplete['AgeGt15'] = complete['Age'] > 15便会在执行时警告您,您可能正在修改不会对起作用的副本train。对于初学者来说,这可能是一个有用的警告。就您而言,您似乎无意通过Modify进行train间接修改complete。因此,警告对您而言只是毫无意义的烦恼。
complete['AgeGt15'] = complete['Age'] > 15
train
complete
您可以通过以下方式使警告静音:
complete.is_copy = False # deprecated as of version 0.24
这是不是让实际的复制更快,而且咬SettingWithCopyWarning在萌芽状态(点这里_check_setitem_copy被称为):
_check_setitem_copy
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。