Изменение порядка уровней MultiIndex в панде DataFrame

У меня есть DataFrame, который выглядит примерно так:

>>> df = pd.DataFrame(index=pd.MultiIndex.from_tuples([(num,letter,color) 
                    for num in range(1,3) 
                    for letter in ['a','b','c'] for color in ['Red','Green']], 
                    names=['Number','Letter','Color']))
>>> df['Value'] = np.random.randint(1,100,len(df))
>>> df
                     Value
Number Letter Color       
1      a      Red       97
              Green     61
       b      Red       97
              Green     98
       c      Red       91
              Green     47
2      a      Red       17
              Green     63
       b      Red       26
              Green     73
       c      Red       34
              Green     68

Но я на самом деле хочу, чтобы мой индекс был упорядочен "Буква, Цвет, Номер".

В настоящее время я делаю это следующим образом:

>>> df.reset_index().set_index(['Letter','Color','Number'])
                     Value
Letter Color Number       
a      Red   1          97
       Green 1          61
b      Red   1          97
       Green 1          98
c      Red   1          91
       Green 1          47
a      Red   2          17
       Green 2          63
b      Red   2          26
       Green 2          73
c      Red   2          34
       Green 2          68

Это лучший подход?

1 ответ

Решение

Лучше использовать reorder_levels манипулировать порядком уровней MultiIndex. Просто передайте список имен / номеров уровней в нужном вам порядке:

>>> df.reorder_levels(['Letter','Color','Number'])
                     Value
Letter Color Number       
a      Red   1          41
       Green 1          56
b      Red   1          43
       Green 1          42
c      Red   1          89
       Green 1          18
a      Red   2          55
       Green 2          93
b      Red   2          64
       Green 2           9
c      Red   2          21
       Green 2          93

Есть также swaplevel если вы просто хотите поменять местами два уровня.

Модификация на месте

Вызов MultiIndex.reorder_levels, затем назначьте новый индекс вашему DataFrame.

df.index = df.index.reorder_levels(['Letter', 'Color', 'Number']) 
df

                     Value
Letter Color Number       
a      Red   1          41
       Green 1          56
b      Red   1          43
       Green 1          42
c      Red   1          89
       Green 1          18
a      Red   2          55
       Green 2          93
b      Red   2          64
       Green 2           9
c      Red   2          21
       Green 2          93

Поскольку объекты индекса неизменяемы, вы не можете отказаться от создания нового индекса, но вы можете избежать дублирования данных, вызвав в противном случае df.reorder_levels.

Другие вопросы по тегам