Как получить доступ к многоуровневому индексу в фрейме данных панд? - PullRequest
2 голосов
/ 14 июня 2019

Я хотел бы назвать эти строки с тем же индексом.

так что это пример фрейма данных,

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], и он не работает. Теперь я уверен, как мне получить доступ к многоуровневому индексу.

Ответы [ 2 ]

2 голосов
/ 14 июня 2019

Используйте 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
1 голос
/ 14 июня 2019

Вы можете использовать нарезку 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
...