【问题标题】:Pandas dataframe boolean mask on multiple columns多列上的 Pandas 数据框布尔掩码
【发布时间】:2017-11-10 11:31:02
【问题描述】:

我有一个数据框 (df),其中包含几个具有实际测量值的列和相应的列数 (A,B,...),每个列的不确定性 (dA, dB, ...):

   A    B    dA      dB
0 -1    3    0.31    0.08
1  2   -4    0.263   0.357
2  5    5    0.382   0.397
3 -4   -0.5  0.33    0.115

我应用一个函数来查找测量列中根据我的定义有效的值

df[["A","B"]].apply(lambda x: x.abs()-5*df['d'+x.name] > 0)

这将返回一个布尔数组:

     A          B 
0    False      True
1    True       True
2    True       True
3    True       False

我想使用这个数组来选择数据框中的行,在单个列中条件为真,例如A -> 行 1-3,还可以找到所有输入列的条件都为真的行,例如第 12 行。 有没有一种有效的方法可以用 pandas 做到这一点?

【问题讨论】:

    标签: python pandas dataframe boolean


    【解决方案1】:

    您可以使用 apply 语句的结果从原始数据帧中选择布尔索引:

    results = df[["A","B"]].apply(lambda x: x.abs()-5*df['d'+x.name] > 0)
    

    返回上面的布尔数组:

           A      B
    0  False   True
    1   True   True
    2   True   True
    3   True  False
    

    现在,您可以使用此数组从原始数据名中选择行,如下所示:

    选择 A 为真:

    df[results.A]
    
       A    B     dA     dB
    1  2 -4.0  0.263  0.357
    2  5  5.0  0.382  0.397
    3 -4 -0.5  0.330  0.115
    

    选择 A 或 B 为真:

    df[results.any(axis=1)]
    
       A    B     dA     dB
    0 -1  3.0  0.310  0.080
    1  2 -4.0  0.263  0.357
    2  5  5.0  0.382  0.397
    3 -4 -0.5  0.330  0.115
    

    选择所有列为真:

    df[results.all(axis=1)]
    
       A    B     dA     dB
    1  2 -4.0  0.263  0.357
    2  5  5.0  0.382  0.397
    

    【讨论】:

    • 没错!这是我最后使用的。也感谢您的努力。
    【解决方案2】:

    使用底层数组数据,向量化的方法会是这样 -

    cols = ['A','B'] # list holding relevant column names
    dcols = ['d'+i for i in cols]
    out = np.abs(df[cols].values) - 5*df[dcols].values > 0
    

    示例运行 -

    In [279]: df
    Out[279]: 
       A    B     dA     dB
    0 -1  3.0  0.310  0.080
    1  2 -4.0  0.263  0.357
    2  5  5.0  0.382  0.397
    3 -4 -0.5  0.330  0.115
    
    In [280]: cols = ['A','B'] # list holding relevant column names
         ...: dcols = ['d'+i for i in cols]
         ...: out = np.abs(df[cols].values) - 5*df[dcols].values > 0
         ...: 
    
    In [281]: out
    Out[281]: 
    array([[False,  True],
           [ True,  True],
           [ True,  True],
           [ True, False]], dtype=bool)
    

    通过将无效的设置为NaNs来提取有效的,我们可以使用np.where -

    In [293]: df[cols] = np.where(out, df[cols], np.nan)
    
    In [294]: df
    Out[294]: 
         A    B     dA     dB
    0  NaN  3.0  0.310  0.080
    1  2.0 -4.0  0.263  0.357
    2  5.0  5.0  0.382  0.397
    3 -4.0  NaN  0.330  0.115
    

    此外,我们可以得到所有匹配的行,每行减少all() -

    In [283]: np.flatnonzero(out.all(axis=1))
    Out[283]: array([1, 2])
    

    【讨论】:

    • 一个非常好的方法,但它只求助于 numpy。,这仍然很好。但是,在使用单个列时,您如何将其映射回数据框 @Divakar?
    • @Fourier 你到底想映射什么?布尔数组out?刚刚对df[cols] = np.where(out, df[cols], np.nan) 进行的编辑对您有用吗?
    • 很抱歉,您的部分答案包括 np.where 在我阅读时尚未出现在页面上。 NVM,过失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2013-05-17
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    相关资源
    最近更新 更多