Панды MultiIndex получают все строки со значением метки

Предположим, у вас есть Panda DataFrame с мультииндексом. Вы хотите получить все строки, которые имеют метку с определенным значением. Как ты это делаешь?

Моей первой мыслью была логическая маска...

df[df.index.labels == 1].head()

но это не работает.

Спасибо!

3 ответа

Решение

Я хотел бы использовать xs (поперечное сечение):

In [11]: df = pd.DataFrame([[1, 2, 3], [3, 4, 5]], columns=list("ABC")).set_index(["A", "B"])

In [12]: df
Out[12]:
     C
A B
1 2  3
3 4  5

тогда вы можете взять те, которые имеют уровень А, равный 1:

In [13]: df.xs(key=1, level="A")
Out[13]:
   C
B
2  3

С помощью drop_level=False делает фильтр (не опуская индекс А):

In [14]: df.xs(key=1, level="A", drop_level=False)
Out[14]:
     C
A B
1 2  3

Вам необходимо указать, какой индекс вы используете. В моем примере я взял второй индекс (Мой фрейм данных s, потому что это было так на странице Multiindex в Pandas):

s[s.index.labels[1]==1]

На самом деле вы можете увидеть, как создается индекс, если наберете:

s.index

Полученная структура:

MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], [1, 2]],
       labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
       names=['first', 'second'])

Ниже у меня есть полный код:

>>> import pandas as pd
>>> import numpy as np
>>> arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
...           [1, 2, 1, 2, 1, 2, 1, 2]]
... 
>>> tuples = list(zip(*arrays))
>>> index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
>>> s = pd.Series(np.random.randn(8), index=index)
>>> s[s.index.labels[1]==1]
first  second
bar    2        -0.304029
baz    2        -1.216370
foo    2         1.401905
qux    2        -0.411468
dtype: float64

Альтернативное решение:

In [62]: df = pd.DataFrame({'idx1': ['A','B','C'], 'idx2':[1,2,3], 'val': [30,10,20]}).set_index(['idx1','idx2'])

In [63]: df
Out[63]:
           val
idx1 idx2
A    1      30
B    2      10
C    3      20

In [64]: df[df.index.get_level_values('idx2') == 2]
Out[64]:
           val
idx1 idx2
B    2      10

In [65]: df[df.index.get_level_values(1) == 2]
Out[65]:
           val
idx1 idx2
B    2      10
Другие вопросы по тегам