如何根据几列中的各个值从multiindex中进行选择?

时间:2019-07-16 20:50:58

标签: python pandas select multi-index

我有一个这样创建的数据框:

import pandas as pd

df = pd.DataFrame({
    'ind1': list('AAABBBCCC'),
    'ind2': list(map(int, list('123123123'))),
    'val1': [0, 0, 0, -1, -4, 5, 10, 11, 4],
    'val2': [0.1, 0.2, -0.2, 0.1, 0.2, 0.2, -0.1, 2, 0.1]
})

df = df.set_index(['ind1', 'ind2'])

结果数据:

           val1  val2
ind1 ind2            
A    1        0   0.1
     2        0   0.2
     3        0  -0.2
B    1       -1   0.1
     2       -4   0.2
     3        5   0.2
C    1       10  -0.1
     2       11   2.0
     3        4   0.1

我要选择以下所有条目:

  1. val1中的至少一项不等于0
  2. val2中的每个绝对值为< 0.5

在上面的示例中,因此仅

B    1       -1   0.1
     2       -4   0.2
     3        5   0.2

应该保留。

我不能使用sum(),因为这些值可以是正数,也可以是负数,所以像这样

df.reset_index().groupby('ind1').sum()

      ind2  val1  val2
ind1                  
A        6     0   0.1
B        6     0   0.5
C        6    25   2.0

不起作用。

我在这里如何使用any()all()

3 个答案:

答案 0 :(得分:2)

transform之前没有lambda

s1=df.val1.ne(0).groupby(level=0).transform('any')
s2=df.val2.abs().lt(0.5).groupby(level=0).transform('all')
df[s1&s2]
Out[583]: 
           val1  val2
ind1 ind2            
B    1       -1   0.1
     2       -4   0.2
     3        5   0.2

答案 1 :(得分:1)

一种方法是通过groupby().filter()link to docs),该方法评估每个组(与每个DataFrame行相对)的布尔条件:

df.groupby('ind1').filter(lambda x: x['val1'].any() & 
                                   (x['val2'].abs() < 0.5).all())

           val1  val2
ind1 ind2            
B    1       -1   0.1
     2       -4   0.2
     3        5   0.2

请注意,DataFrame.groupby.filter()与同名方法DataFrame.filter()无关!

答案 2 :(得分:1)

这对我有用,类似于Wen的解决方案:

mask = df.abs().groupby(level=0).transform('max')
df[mask.val1.gt(0)&mask.val2.lt(0.5)]

输出:

           val1  val2
ind1 ind2            
B    1       -1   0.1
     2       -4   0.2
     3        5   0.2