Skip to main content
 首页 » 编程设计

python之使用 MultiIndex 有条件地选择 pandas DataFrame 中的行

2025年05月04日21bonelee

我有一个像这样的 DataFrame:

df = pd.DataFrame(np.random.randn(6, 6), 
                  columns=pd.MultiIndex.from_arrays((['A','A','A','B','B','B'],  
                                                     ['a', 'b', 'c', 'a', 'b', 'c']))) 
df 
          A                             B                     
          a         b         c         a         b         c 
0 -0.089902 -2.235642  0.282761  0.725579  1.266029 -0.354892 
1 -1.753303  1.092057  0.484323  1.789094 -0.316307  0.416002 
2 -0.409028 -0.920366 -0.396802 -0.569926 -0.538649 -0.844967 
3  1.789569 -0.935632  0.004476 -1.873532 -1.136138 -0.867943 
4  0.244112  0.298361 -1.607257 -0.181820  0.577446  0.556841 
5  0.903908 -1.379358  0.361620  1.290646 -0.523404 -0.518992 

我只想选择 c 列中值大于 0 的行。我认为我将不得不使用 pd.IndexSlice 来仅选择二级索引 c。

idx = pd.IndexSlice 
df.loc[:,idx[:,['c']]] > 0 
       A      B 
       c      c 
0   True  False 
1   True   True 
2  False  False 
3   True  False 
4  False   True 
5   True  False 

所以,现在我希望我可以简单地执行 df[df.loc[:,idx[:,['c']]] > 0],但这给了我一个意想不到的结果结果:

df[df.loc[:,idx[:,['c']]] > 0] 
    A                 B               
    a   b         c   a   b         c 
0 NaN NaN  0.282761 NaN NaN       NaN 
1 NaN NaN  0.484323 NaN NaN  0.416002 
2 NaN NaN       NaN NaN NaN       NaN 
3 NaN NaN  0.004476 NaN NaN       NaN 
4 NaN NaN       NaN NaN NaN  0.556841 
5 NaN NaN  0.361620 NaN NaN       NaN 

我想要的是所有值(不是 NaN)并且只有任何 c 列大于 0 的行。

          A                             B                     
          a         b         c         a         b         c 
0 -0.089902 -2.235642  0.282761  0.725579  1.266029 -0.354892 
1 -1.753303  1.092057  0.484323  1.789094 -0.316307  0.416002 
3  1.789569 -0.935632  0.004476 -1.873532 -1.136138 -0.867943 
4  0.244112  0.298361 -1.607257 -0.181820  0.577446  0.556841 
5  0.903908 -1.379358  0.361620  1.290646 -0.523404 -0.518992 

因此,我可能需要在其中某处偷偷添加一个 any(),但是,我不确定该怎么做。有什么提示吗?

请您参考如下方法:

另一个版本使用get_level_values

df[(df.iloc[:, df.columns.get_level_values(1) == 'c'] > 0).any(axis=1)]