Иерархическое индексирование и уровни признаков / pd 6

Иерархическое индексирование — это важная особенность pandas, поскольку она позволяет иметь несколько уровней индексов в одной оси. С ее помощью можно работать с данными в большом количестве измерений, по-прежнему используя для этого структуру данных из двух измерений.

Начнем с простого примера, создав Series с двумя массивами индексов — структуру с двумя уровнями.

>>> mser = pd.Series(np.random.rand(8),
...  	     index=[['white','white','white','blue','blue','red','red',
 'red'],
... 		    ['up','down','right','up','down','up','down','left']])
>>> mser
white  up       0.661039
       down     0.512268
       right    0.639885
blue   up       0.081480
       down     0.408367
red    up       0.465264
       down     0.374153
       left     0.325975
dtype: float64
>>> mser.index
MultiIndex(levels=[['blue', 'red', 'white'], ['down', 'left', 'right', 'up']],
           labels=[[2, 2, 2, 0, 0, 1, 1, 1], [3, 0, 2, 3, 0, 3, 0, 1]])

За счет спецификации иерархического индексирования, выбор подмножеств значений в таком случае заметно упрощен. Можно выбрать значения для определенного значения первого индекса стандартным способом:

>>> mser['white']
up       0.661039
down     0.512268
right    0.639885
dtype: float64

Или же значения для конкретного значения во втором индекса — таким:

>>> mser[:,'up']
white    0.661039
blue     0.081480
red      0.465264
dtype: float64

Если необходимо конкретное значение, просто указываются оба индекса.

>>> mser['white','up']
0.66103875558038194

Иерархическое индексирование играет важную роль в изменении формы данных и групповых операциях, таких как сводные таблицы. Например, данные могут быть перестроены и использованы в объекте Dataframe с помощью функции unstack(). Она конвертирует Series с иерархическими индексами в простой Dataframe, где второй набор индексов превращается в новые колонки.

>>> mser.unstack()
down left right up
blue 0.408367 NaN NaN 0.081480
red 0.374153 0.325975 NaN 0.465264
white 0.512268 NaN 0.639885 0.661039

Если необходимо выполнить обратную операцию — превратить Dataframe в Series, — используется функция stack().

>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
>>> frame.stack()
red     ball       0
        pen        1
        pencil     2
        paper      3
blue    ball       4
        pen        5
        pencil     6
        paper      7
yellow  ball       8
        pen        9
        pencil    10
        paper     11
white   ball      12
        pen       13
        pencil    14
        paper     15
dtype: int32

В Dataframe можно определить иерархическое индексирование для строк и колонок. Для этого необходимо определить массив массивов для параметров index и columns.

>>> mframe = pd.DataFrame(np.random.randn(16).reshape(4,4),
... 			  index=[['white','white','red','red'], ['up','down','up','down']],
... 			  columns=[['pen','pen','paper','paper'],[1,2,1,2]])
>>> mframe
pen paper
1 2 1 2
white up 1.562883 0.919727 -0.397509 -0.314159
down 0.580848 1.124744 0.741454 -0.035455
red up -1.721348 0.989703 -1.454304 -0.249718
down -0.113246 -0.441528 -0.105028 0.285786

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

Иногда потребуется поменять порядок уровней на оси или отсортировать значения на определенном уровне.

Функция swaplevel() принимает в качестве аргументов названия уровней, которые необходимо поменять относительно друг друга и возвращает новый объект с соответствующими изменениями, оставляя данные в том же состоянии.

>>> mframe.columns.names = ['objects','id']
>>> mframe.index.names = ['colors','status']
>>> mframe
objects pen paper
id 1 2 1 2
colors status
white up 1.562883 0.919727 -0.397509 -0.314159
down 0.580848 1.124744 0.741454 -0.035455
red up -1.721348 0.989703 -1.454304 -0.249718
down -0.113246 -0.441528 -0.105028 0.285786
>>> mframe.swaplevel('colors','status')
objects pen paper
id 1 2 1 2
status colors
up white 1.562883 0.919727 -0.397509 -0.314159
down white 0.580848 1.124744 0.741454 -0.035455
up red -1.721348 0.989703 -1.454304 -0.249718
down red -0.113246 -0.441528 -0.105028 0.285786

А функция sort_index() сортирует данные для конкретного уровня, указанного в параметрах.

>>> mframe.sort_index(level='colors')
objects pen paper
id 1 2 1 2
colors status
red down -0.113246 -0.441528 -0.105028 0.285786
up -1.721348 0.989703 -1.454304 -0.249718
white down 0.580848 1.124744 0.741454 -0.035455
up 1.562883 0.919727 -0.397509 -0.314159

Общая статистика по уровню

У многих статистических методов для Dataframe есть параметр level, в котором нужно определить, для какого уровня нужно определить статистику.

Например, если нужна статистика для первого уровня, его нужно указать в параметрах.

 >>> mframe.sum(level='colors')
objects pen paper
id 1 2 1 2
colors
white 2.143731 2.044471 0.343945 -0.349614
red -1.834594 0.548174 -1.559332 0.036068

Если же она необходима для конкретного уровня колонки, например, id, тогда требуется задать параметр axis и указать значение 1.

>>> mframe.sum(level='id', axis=1)
id 1 2 paper
colors status
white up 1.165374 0.605568
down 1.322302 1.089289
red up -3.175653 0.739985
down -0.218274 -0.155743

Появились вопросы? Задайте на Яндекс Кью

У блога есть сообщество на Кью, подписывайтесь >> Python Q << и задавайте вопросы. Спрашивайте по контенту, про python и программирование в целом.

Обучение с трудоустройством

Профессия Python-разработчик / Skillbox

Профессия Python-разработчик / Skillbox

6 500 3 900 ₽/мес.
Факультет Python-разработки / GeekBrains

Факультет Python-разработки / GeekBrains

4 990 ₽/мес.
Профессия Fullstack-разработчик / Skillfactory

Профессия Fullstack-разработчик / SkillFactory

12 500 6 250 ₽/мес.
Профессия Data Scientist / Skillbox

Профессия Data Scientist / Skillbox

8 167 4 900 ₽/мес.

Вам помогла эта статья? Поделитесь в соцсетях или блоге. Репосты помогают сайту развиться.

Александр
Я создал этот блог в 2018 году, чтобы распространять полезные учебные материалы, документации и уроки на русском. На сайте опубликовано множество статей по основам python и библиотекам, уроков для начинающих и примеров написания программ.