如何在Pandas数据框中访问多层索引?

7

我希望能够调用相同索引的行。

以下是数据框示例:

arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]

df = pd.DataFrame(np.random.randn(8, 4), index=arrays)

In [16]: df
Out[16]: 
                0         1         2         3
bar one -0.424972  0.567020  0.276232 -1.087401
    two -0.673690  0.113648 -1.478427  0.524988
baz one  0.404705  0.577046 -1.715002 -1.039268
    two -0.370647 -1.157892 -1.344312  0.844885
foo one  1.075770 -0.109050  1.643563 -1.469388
    two  0.357021 -0.674600 -1.776904 -0.968914
qux one -1.294524  0.413738  0.276662 -0.472035
    two -0.013960 -0.362543 -0.006154 -0.923061

我想要选择

                0         1         2         3
bar one -0.424972  0.567020  0.276232 -1.087401
baz one  0.404705  0.577046 -1.715002 -1.039268
foo one  1.075770 -0.109050  1.643563 -1.469388
qux one -1.294524  0.413738  0.276662 -0.472035

甚至可以作为这种格式

            0         1         2         3
one -0.424972  0.567020  0.276232 -1.087401
one  0.404705  0.577046 -1.715002 -1.039268
one  1.075770 -0.109050  1.643563 -1.469388
one -1.294524  0.413738  0.276662 -0.472035

我尝试过df['bar','one'],但它没有起作用。我现在不确定如何访问多级索引。

3个回答

5
您可以使用MultiIndex切片(使用slice(None)而不是冒号):
df = df.loc[(slice(None), 'one'), :]

结果:

                0         1         2         3
bar one -0.424972  0.567020  0.276232 -1.087401
baz one  0.404705  0.577046 -1.715002 -1.039268
foo one  1.075770 -0.109050  1.643563 -1.469388
qux one -1.294524  0.413738  0.276662 -0.472035

最后,您可以删除第一个索引列:

df.index = df.index.droplevel(0)

结果:

            0         1         2         3
one -0.424972  0.567020  0.276232 -1.087401
one  0.404705  0.577046 -1.715002 -1.039268
one  1.075770 -0.109050  1.643563 -1.469388
one -1.294524  0.413738  0.276662 -0.472035

2

使用DataFrame.xs函数,如果需要两个级别,请添加drop_level=False参数:


df1 = df.xs('one', level=1, drop_level=False)
print (df1)
bar one -0.424972  0.567020  0.276232 -1.087401
baz one  0.404705  0.577046 -1.715002 -1.039268
foo one  1.075770 -0.109050  1.643563 -1.469388
qux one -1.294524  0.413738  0.276662 -0.472035

使用DataFrame.reset_index函数并设置drop=True可以删除第一层级,然后可以使用DataFrame.loc按标签进行选择:


df2 = df.reset_index(level=0, drop=True).loc['one']
#alternative
#df2 = df.xs('one', level=1, drop_level=False).reset_index(level=0, drop=True)
print (df2)
            0         1         2         3
one -0.424972  0.567020  0.276232 -1.087401
one  0.404705  0.577046 -1.715002 -1.039268
one  1.075770 -0.109050  1.643563 -1.469388
one -1.294524  0.413738  0.276662 -0.472035

更常见的做法是使用不带重复级别的xs - 因此在选择one后,将删除此级别:
df3 = df.xs('one', level=1)
print (df3)
            0         1         2         3
bar -0.424972  0.567020  0.276232 -1.087401
baz  0.404705  0.577046 -1.715002 -1.039268
foo  1.075770 -0.109050  1.643563 -1.469388
qux -1.294524  0.413738  0.276662 -0.472035

0

由于这个问题涉及到多重索引,而且索引的顺序是'bar'然后是'one',可以通过使用df.index命令进行验证:

MultiIndex([('bar', 'one'),
            ('bar', 'two'),
            ('baz', 'one'),
            ('baz', 'two'),
            ('foo', 'one'),
            ('foo', 'two'),
            ('qux', 'one'),
            ('qux', 'two')],
           )

您要查找的输出可以使用df.loc[('bar','one')]访问

它产生的输出是

0    0.162693
1    0.420518
2   -0.152041
3   -1.039439
Name: (bar, one), dtype: float64

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