根据其他包含空值的列使用掩码设置值

时间:2018-12-25 10:22:35

标签: python pandas

我想检查某些列(大约5或6),如果所有列都为空,请将另一列has_nan0更改为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'

4 个答案:

答案 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以获得详细说明。