【问题标题】:Pandas: `or` operation on NaN valuesPandas:对 NaN 值进行“或”操作
【发布时间】:2021-07-06 17:43:55
【问题描述】:

我有一个包含 3 列的 DataFrame,每个列的值都可以是 NaN。 我想根据这 3 列填充第 4 列,以便在列上应用 or 操作:如果第 1 列不是 NaN,则取其值,否则检查第 2 列等。 由于NaN 值不是False,因此or 运算符不能按原样使用。 这是我附带的代码,但它不是 Pythonic 或 Pandas-ic。是否有内置功能可以做到这一点?或者,如果您有任何其他建议?

import pandas as pd
import numpy as np

nan = np.NaN
df = pd.DataFrame({"a": [nan, 1, nan], "b": [2, nan, nan], "c": [nan, nan, 3]})
#   a   b   c
# 0 NaN 2.0 NaN
# 1 1.0 NaN NaN
# 2 NaN NaN 3.0

nan_to_false = lambda val: False if pd.isna(val) else val

df["a_or_b_or_c"] = df.apply(lambda row: nan_to_false(row["a"]) or nan_to_false(row["b"]) or nan_to_false(row["c"]), axis=1)
# 0    2.0
# 1    1.0
# 2    3.0

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    想法是回填缺失值,然后选择第一列:

    df["all columns"] = df.bfill(axis=1).iloc[:, 0]
    

    如果需要过滤列名:

    df["a_or_b_or_c"] = df[['a','b','c']].bfill(axis=1).iloc[:, 0]
    

    【讨论】:

    • 如果第一个值为0怎么办?
    • @juanpa.arrivillaga - 然后没有repalced。
    • 好吧,准确地说。然后将其作为值,但这不是 OP 想要的。因此,请使用 df.iat[0,0] = 0 并针对 OP 测试您的解决方案的输出
    • @jezrael,这对我有用 df.bfill(axis=1) ,那么我们为什么需要 iloc[:, 0]
    • @hackwithharsha - 因为需要选择第一列,所以不需要输出其他列。
    【解决方案2】:

    在我看来,一行中只有一个非缺失值。你可以试试这个技巧

    import pandas as pd
    import numpy as np
    
    nan = np.NaN
    df = pd.DataFrame({"a": [nan, 1, nan], "b": [2, nan, nan], "c": [nan, nan, 3]})
    
    fn = lambda x: np.max(x)
    df["a_or_b_or_c"] = df[["a", "b", "c"]].apply(fn, axis=1)
    
    #
         a    b    c  a_or_b_or_c
    0  NaN  2.0  NaN          2.0
    1  1.0  NaN  NaN          1.0
    2  NaN  NaN  3.0          3.0
    

    【讨论】:

    • 另外,fn = lambda x: np.max(x) 可以只是 np.max... 即 apply(np.max)但您不应该将 .apply 向量化函数只需使用矢量化方法开始
    猜你喜欢
    • 1970-01-01
    • 2018-02-01
    • 2019-04-07
    • 2019-06-23
    • 1970-01-01
    • 2017-02-24
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多