Ответ 1
Один из способов - использовать index.levels
:
In [11]: df
Out[11]:
C
A B
0 one 3
1 one 2
2 two 1
In [12]: df.index.levels[1]
Out[12]: Index([one, two], dtype=object)
Я знаю, что могу получить уникальные значения DataFrame
путем сброса индекса, но есть ли способ избежать этого шага и получить уникальные значения напрямую?
Учитывая, что у меня есть:
C
A B
0 one 3
1 one 2
2 two 1
Я могу сделать:
df = df.reset_index()
uniq_b = df.B.unique()
df = df.set_index(['A','B'])
Есть ли способ, построенный в pandas для этого?
Один из способов - использовать index.levels
:
In [11]: df
Out[11]:
C
A B
0 one 3
1 one 2
2 two 1
In [12]: df.index.levels[1]
Out[12]: Index([one, two], dtype=object)
Ответ Энди Хайдена (index.levels[blah]
) отлично подходит для некоторых сценариев, но может привести к странному поведению в других. Мое понимание заключается в том, что Pandas подходит для "повторного использования" индексов, когда это возможно, чтобы избежать того, чтобы индексы много одинаковых индексов DataFrames занимали пространство в памяти. В результате я нашел следующее неприятное поведение:
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')
Как заметил один человек в другой теме, одна идиома, которая кажется очень естественной и работает правильно, будет:
small.index.get_level_values('Person').unique()
large.index.get_level_values('Person').unique()
Надеюсь, это поможет кому-то еще избежать невероятно неожиданного поведения, с которым я столкнулся.