【问题标题】:Creating new column containing Booleans or NaN based on values in other columns in the same pandas dataframe根据同一熊猫数据框中其他列中的值创建包含布尔值或 NaN 的新列
【发布时间】:2019-09-19 15:50:09
【问题描述】:

我想在 pandas 数据框中创建一个新列,该列的计算结果为 True、False 或 NaN,具体取决于在同一数据框中的其他两列中找到的值,这两个列也仅包含 True、False 或 NaN 值。具体来说,如下图,新列中的行值应该是: (a) 如果任一参考列值为 True,则为 True, (b) 如果两个参考列值都是 False,或者它们是 False 和 NaN 的组合,则为 False,或者 (c) 如果两个参考列的值都是 NaN,则为 NaN。

col_A + col_B => new_col(期望值)

  • 真 + 真 => 真
  • 真 + 假 => 真
  • 真 + NaN => 真
  • 假 + 假 => 假
  • 假 + NaN => 假
  • NaN + NaN => NaN

最初,如下所示,我尝试将值分配给 col_A 或 col_B 为 True 的新列,但可以理解的是,只要一列或两列包含 NaN,它就会返回 False。

df[new_col] = df[col_A] | df[col_B]

我还想出了如何为 col_A 和 col_B 均为 NaN 的行创建一个返回 True 的列,但我仍在努力找出下一步。

df[new_col] = pd.isnull(df[col_A]) & pd.isnull(df[col_B]) 

我觉得我最终可以使用 for 循环/if 语句获得正确的输出,但我的理解是这将非常低效,而且似乎应该有一种更有效/更直接的方式来获得结果我'我正在寻找。

【问题讨论】:

    标签: pandas


    【解决方案1】:

    使用.any

    设置数据框:

    dict = {
        'col_A': [True, True, True, False, False, False, np.NaN, np.NaN, np.NaN], 
        'col_B': [True, False, np.NaN, False, True, np.NaN, np.NaN,True, False]   
           }
    df = pd.DataFrame(dict)
    
    print(df)
    
       col_A  col_B
    0   True   True
    1   True  False
    2   True    NaN
    3  False  False
    4  False   True
    5  False    NaN
    6    NaN    NaN
    7    NaN   True
    8    NaN  False
    

    创建一个新列并将所有值设置为 false。我们将填写其他值。

    df['new_col'] = False
    

    使用 .any() 填充剩余的 True 和 NaN 值。

    df.loc[df[['col_A', 'col_B']].any(1), 'new_col'] = True
    

    打印(df)

       col_A   col_B   new_col
    0   True   True     True
    1   True  False     True
    2   True    NaN     True
    3  False  False    False
    4  False   True     True
    5  False    NaN    False
    6    NaN    NaN    False
    7    NaN   True     True
    8    NaN  False    False
    

    【讨论】:

    • 这让我很接近,因为所有 True 都被正确解释,但如第 6 行所示,当两者都是 NaN 时,它仍然导致 False 而不是 NaN。为了解决这个问题,我插入了df.loc[df[['col_A', 'col_B']].isnull().all(1), 'new_col'] = np.nan,它解决了这个问题,但又产生了另一个小问题,因为 new_col 中的值随后显示为 1/0/NaN 而不是 True/False/NaN。因此,为了保持一致性,我在最后使用以下代码将 1/0 重新转换为 True/False。 df_dict = {1:True, 0:False}df['new_col'] = df['new_col'].map(df_dict)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 2019-07-25
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多