Pandas数据框多列布尔掩码

6

我有一个数据框(df),其中包含若干列实际测量值和对应的每个列的不确定度(A,B,...):

   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 中有没有高效的方法实现这个功能?

2个回答

3

您可以使用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 为 True 的行:

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

选择所有列都为true的位置:

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

没错!这就是我最终使用的。也谢谢你的努力。 - Fourier

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
1
@Fourier 你想要映射回什么?布尔数组 out 吗?刚刚做的 df[cols] = np.where(out, df[cols], np.nan) 的修改对你有用吗? - Divakar
很抱歉,当我阅读时,您的答案中包含np.where的部分还未出现在页面上。没关系,是我的错。 - Fourier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接