#python #pandas #multi-index
#python #панды #мультииндексный
Вопрос:
Допустим, у меня есть большой large
фрейм данных, который имеет мультииндекс в строках. Я сокращаю этот фрейм данных, выбирая только некоторые строки и присваивая результат small
. В частности, small
имеет меньше различных значений на 0-м уровне своего мультииндекса в строках, чем large
.
Затем я хочу получить список различных значений на 0-м уровне MultiIndex в строках small
, которые я вызываю small.index.levels[0]
. Результат странный: он возвращает то же самое, large.index.levels[0]
что и несмотря на то, что значений должно быть меньше.
Что происходит?
MWE:
import pandas as pd
import numpy as np
np.random.seed(0)
idx = pd.MultiIndex.from_product([['John', 'Josh', 'Alex'], list('abcde')],
names=['Person', 'Letter'])
large = pd.DataFrame(data=np.random.randn(15, 2),
index=idx,
columns=['one', 'two'])
small = large.loc[['Jo'==d[0:2] for d in large.index.get_level_values('Person')]]
print small.index.levels[0]
print large.index.levels[0]
Вывод:
Index([u'Alex', u'John', u'Josh'], dtype='object')
Index([u'Alex', u'John', u'Josh'], dtype='object')
Ожидаемый результат:
Index([u'John', u'Josh'], dtype='object')
Index([u'Alex', u'John', u'Josh'], dtype='object')
Ответ №1:
Более эффективно это сделать.
In [43]: large[large.index.get_level_values('Person').to_series().str.startswith('Jo').values]
Out[43]:
one two
Person Letter
John a 1.764052 0.400157
b 0.978738 2.240893
c 1.867558 -0.977278
d 0.950088 -0.151357
e -0.103219 0.410599
Josh a 0.144044 1.454274
b 0.761038 0.121675
c 0.443863 0.333674
d 1.494079 -0.205158
e 0.313068 -0.854096
Чтобы ответить на ваш вопрос. Это деталь реализации. Использовать .get_level_values()
(вместо доступа к внутреннему .levels
Вы можете сделать это, если хотите.
In [13]: small.index.get_level_values('Person').unique()
Out[13]: array(['John', 'Josh'], dtype=object)
In [14]: large.index.get_level_values('Person').unique()
Out[14]: array(['John', 'Josh', 'Alex'], dtype=object)
Комментарии:
1. Я не совсем уверен, что вы ответили на мой вопрос. Моя цель — не выполнять фильтрацию от
large
доsmall
. В моемsmall
приведенном выше есть только те данные, которые мне нужны. Я хочу получить список различных значений на 0-м уровне мультииндексаsmall
. (Например,large
наPerson
уровне его MultiIndex могут быть сотни имен, и поэтому я могу не знать, что я получу, когда отфильтрую только имена, начинающиеся с'Jo'
. Но как только фильтрация будет завершена, я хочу посмотреть, что у меня получилось. Как вы предлагаете мне это сделать?