Pandas: получить уникальные значения уровня MultiIndex по метке
Предположим, что у вас есть этот MultiIndex-ed DataFrame:
df = pd.DataFrame({'co':['DE','DE','FR','FR'],
'tp':['Lake','Forest','Lake','Forest'],
'area':[10,20,30,40],
'count':[7,5,2,3]})
df = df.set_index(['co','tp'])
Что выглядит так:
area count
co tp
DE Lake 10 7
Forest 20 5
FR Lake 30 2
Forest 40 3
Я бы хотел получить уникальные значения на уровне индекса. Это можно сделать, используя
df.index.levels[0] # returns ['DE', 'FR]
df.index.levels[1] # returns ['Lake', 'Forest']
Что бы я хотел сделать, это получить эти списки с помощью , обращаясь к уровням по имени, т.е. 'co'
и 'tp'
. Самый короткий два пути, которые я мог найти, выглядит так:
list(set(df.index.get_level_values('co'))) # returns ['DE', 'FR']
df.index.levels[df.index.names.index('co')] # returns ['DE', 'FR']
Но не из них очень изящны. Есть ли более короткий путь?
Ответы
Ответ 1
Я предполагаю, что у вас нужны уникальные значения на определенном уровне (и по именам уровней) мультииндекса. Обычно я делаю следующее, что немного длиннее.
In [11]: df.index.get_level_values('co').unique()
Out[11]: array(['DE', 'FR'], dtype=object)
Ответ 2
Альтернативный подход - найти количество уровней, вызвав df.index.levels[level_index]
, где level_index может быть выведен из df.index.names.index(level_name)
. В приведенном выше примере level_name = 'co'.
Предлагаемый ответ @Happy001 вычисляет уникальный, который может быть интенсивным с точки зрения вычислительной мощности.
Ответ 3
Если вы собираетесь повторно выполнять поиск уровня, вы можете создать карту имен ваших индексных уровней для определения уникальных значений с помощью:
df_level_value_map = {
name: level
for name, level in zip(df.index.names, df.index.levels)
}
df_level_value_map['']
Но это никоим образом не является более эффективным (или короче), чем ваши первоначальные попытки, если вы только собираетесь сделать этот поиск один раз.
Мне очень жаль, что не было метода индексов, который возвращал такой словарь (или серию?) с таким именем, как:
df.index.get_level_map(levels={...})
Если параметр уровня может ограничить отображение подмножеством существующих уровней. Я мог бы обойтись без параметра, если это может быть свойство вроде:
df.index.level_map