代码之家  ›  专栏  ›  技术社区  ›  Josh Friedlander

基于包含空值的其他列使用掩码设置值

  •  3
  • Josh Friedlander  · 技术社区  · 6 年前

    我想检查某些列(大约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'
    
    4 回复  |  直到 6 年前
        1
  •  4
  •   jpp    5 年前

    Avoid chained indexing. 在这里,您可以使用布尔级数:

    df['has_nan'] = df[['use_1', 'use_2']].isnull().all(1)
    

    使用布尔级数,即包含 True / False 推荐 方法如果你坚持要转换成 'yes' / 'no' 字符串,您可以通过字典映射在后续步骤中执行此操作:

    mapper = {1: 'yes', 0: 'no'}
    df['has_nan'] = df['has_nan'].map(mapper)
    
        2
  •  1
  •   anky    6 年前

    你是说这个

    df['has_nan'][df['column_name'].isna()] = 0
    df['has_nan'][~df['column_name'].isna()] = 1
    
        3
  •  1
  •   gosuto    6 年前

    尝试 df.loc[df.use_1.isna() & df.use_2.isna(), 'has_nan'] = 'yes' 相反

    https://www.dataquest.io/blog/settingwithcopywarning/

        4
  •  0
  •   Sabih    6 年前

    一种方法是:

    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 详细解释。