DataFrame MultiIndex - 根据值查找列

3

我有一个包含两层索引和约100列的多重索引数据框。 我想根据特定值的存在获取值组(以列为组织),但是我仍然在处理索引机制上遇到困难。

这里是一些示例数据:

import pandas as pd

index_arrays = [np.array(["one"]*5+["two"]*5), 
                np.array(["aaa","bbb","ccc","ddd","eee"]*2)]

df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9],
                   [10,11,12],[13,14,15],[16,1,17],
                   [18,19,20],[21,22,23],[24,25,26],
                   [27,28,29]], index=index_arrays)

提供

          0   1   2
one aaa   1   2   3
    bbb   4   5   6
    ccc   7   8   9
    ddd  10  11  12
    eee  13  14  15
two aaa  16   1  17
    bbb  18  19  20
    ccc  21  22  23
    ddd  24  25  26
    eee  27  28  29

现在,对于每个 level_0 索引(onetwo),我希望返回整个列,其中 level_1 索引为 aaa 的值等于某个特定值,例如 1。 目前我的代码如下:
df[df.loc[(slice(None), "aaa"),:]==1].any(axis=1)
>
one  aaa     True
     bbb    False
     ccc    False
     ddd    False
     eee    False
two  aaa     True
     bbb    False
     ccc    False
     ddd    False
     eee    False

我想要获取实际的值而不是布尔类型的值。期望输出如下:

expected:
          0
one aaa   1
    bbb   4
    ccc   7
    ddd  10
    eee  13
two aaa   1
    bbb  19
    ccc  22
    ddd  25
    eee  28

我很感激你的帮助。

额外问题: 此外,知道包含所需值的列是哪一列也会很好。 对于上面的示例,这将是第0列(对于索引one)和第1列(对于索引two)。有方法可以做到这一点吗? 谢谢!

2个回答

1
让我们尝试使用 DataFrame.xs
m = df.xs('aaa', level=1).eq(1).any()

或者使用 pd.IndexSlice
m = df.loc[pd.IndexSlice[:, 'aaa'], :].eq(1).any()

结果:

df.loc[:, m]

          0   1
one aaa   1   2
    bbb   4   5
    ccc   7   8
    ddd  10  11
    eee  13  14
two aaa  16   1
    bbb  18  19
    ccc  21  22
    ddd  24  25
    eee  27  28

df.columns[m]

Int64Index([0, 1], dtype='int64')

1
这可能是您正在寻找的内容:
df.loc[df.index.get_level_values(0) == 'one', df.loc[('one', 'aaa')] == 1]

这段文本的英译为:“这将输出:”。
          0
one aaa   1
    bbb   4
    ccc   7
    ddd  10
    eee  13

要将第一个索引的所有不同值的结果组合起来,请生成这些数据帧并将它们连接起来:
output_df = pd.DataFrame()
for level_0_val in df.index.get_level_values(0).unique():
    _ = df.loc[df.index.get_level_values(0) == level_0_val, df.loc[(level_0_val, 'aaa')] == 1]
    output_df = output_df.append(_)

这是 output_df:

            0     1
one aaa   1.0   NaN
    bbb   4.0   NaN
    ccc   7.0   NaN
    ddd  10.0   NaN
    eee  13.0   NaN
two aaa   NaN   1.0
    bbb   NaN  19.0
    ccc   NaN  22.0
    ddd   NaN  25.0
    eee   NaN  28.0

你可以从这里生成所需的输出。

这确实是我在寻找的输出结果。然而,我希望有一种不需要 for 循环 的解决方案,但情况似乎比我想象的更加复杂。感谢您的回答! - BenB
太好了!现在一个没有for循环的解决方案会更棒... - Baran Karakus

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