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

我会很感激你的帮助。

奖励问题:此外,很高兴知道哪一列包含有问题的值。对于上面的示例,这将是column 0(for index one) 和column 1(for index two)。有没有办法做到这一点?谢谢!

4

2 回答 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')
于 2020-12-30T12:41:52.580 回答
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

要组合第一个索引的所有不同值的结果,请生成这些 DataFrame 并将它们连接起来:

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

然后,您可以从中生成所需的输出。

于 2020-12-30T12:44:25.130 回答