Подтвердить что ты не робот

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']

Но не из них очень изящны. Есть ли более короткий путь?

4b9b3361

Ответ 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