我想检查某些列(大约5或6),如果所有列都为空,请将另一列has_nan
从0
更改为1
。我知道如何过滤/屏蔽,但是使用loc
时,我会感到恐惧SettingWithCopyWarning
。
这是一个小的示例,虽然不完全相同,但突出了问题所在:
df = pd.DataFrame([np.random.randint(0,100,3), np.random.randint(0,100,3),
np.random.randint(0,100,3), np.random.randint(0,100,3)],
columns=['foo', 'bar', 'has_nan'])
for i in ['use_1', 'use_2']:
df[i] = 2 * ['5'] + 2 * [np.nan]
df.loc[df.use_1.isna() & df.use_2.isna()]['has_nan'] = 'yes'
答案 0 :(得分:3)
Avoid chained indexing.在这里您可以使用布尔系列:
df['has_nan'] = df[['use_1', 'use_2']].isnull().any(1)
使用布尔序列,即仅包含True
/ False
值的布尔序列是 recommended 方法。如果您坚持要转换为'yes'
/ 'no'
字符串,则可以在随后的步骤中通过字典映射来实现:
mapper = {1: 'yes', 0: 'no'}
df['has_nan'] = df['has_nan'].map(mapper)
答案 1 :(得分:1)
这是你的意思吗? :
df['has_nan'][df['column_name'].isna()] = 0
df['has_nan'][~df['column_name'].isna()] = 1
答案 2 :(得分:1)
改为尝试df.loc[df.use_1.isna() & df.use_2.isna(), 'has_nan'] = 'yes'
。
有关更多信息,我阅读了https://www.dataquest.io/blog/settingwithcopywarning/
答案 3 :(得分:0)
一种方法是:
df['has_nan'][df.use_1.isna() & df.use_2.isna()] = 'yes'
执行以下操作时,它将返回一个副本(这是警告的目的),并且将不起作用:
df.loc[df.use_1.isna() & df.use_2.isna()]['has_nan'] = 'yes'
这两种方法都会发出警告,您可以使用以下方法将其静音:
pd.set_option('mode.chained_assignment', None)
阅读Evaluation order matters以获得详细说明。