过滤多索引

Wag*_*ver 7 python multi-index pandas

C1 C2 C3 C4
A 12 真的 89
9 错误的 77
5 真的 23
9 真的 45
5 真的 45
2 错误的 78
C 11 真的 10
8 错误的 08
12 错误的 09

C1 和 C2 是多重索引。我希望得到的结果只给出 C1 中的值,而 C2 中的值既小于 10 又大于或等于 10。

因此,上表中的 C1 - B 应该消失,最终结果应如下所示:

C1 C2 C3 C4
A 12 真的 89
9 错误的 77
5 真的 23
C 11 真的 10
8 错误的 08
12 错误的 09

我尝试了 df.loc[(df.C2 < 10 ) & (df.C2 >= 10)] 但这不起作用。

我也尝试过:

过滤器1 = df.index.get_level_values('C2') < 10 过滤器2 = df.index.get_level_values('C2') >= 10

df.iloc[过滤器1 & 过滤器2]

我在另一篇文章中看到的建议也不起作用。有人知道如何解决这个问题吗?谢谢

jez*_*ael 2

使用GroupBy.transformwithGroupBy.any来测试每组至少一个条件匹配,因此可能通过mDataFrame 最后进行过滤:

filter1 = df.index.get_level_values('C2') < 10 
filter2 = df.index.get_level_values('C2') >= 10

m = (df.assign(filter1= filter1, filter2=filter2)
       .groupby(level=0)[['filter1','filter2']]
       .transform('any'))

print (m)
       filter1  filter2
C1 C2                  
A  12     True     True
   9      True     True
   5      True     True
B  9      True    False
   5      True    False
   2      True    False
C  11     True     True
   8      True     True
   12     True     True
Run Code Online (Sandbox Code Playgroud)
df = df[m.filter1 & m.filter2]
print (df)
          C3  C4
C1 C2           
A  12   True  89
   9   False  77
   5    True  23
C  11   True  10
   8   False   8
   12  False   9
Run Code Online (Sandbox Code Playgroud)

替代解决方案:

filter1 = df.index.get_level_values('C2') < 10 
filter2 = df.index.get_level_values('C2') >= 10

lvl1 = df.index[filter1].remove_unused_levels().levels[0]
lvl2 = df.index[filter2].remove_unused_levels().levels[0]

df1 = df.loc[set(lvl1).intersection(lvl2)]
print (df1)
          C3  C4
C1 C2           
A  12   True  89
   9   False  77
   5    True  23
C  11   True  10
   8   False   8
   12  False   9
Run Code Online (Sandbox Code Playgroud)