pandas: как запустить ось с мультииндексированием?

Я хотел бы запустить опорный элемент в кадре данных pandas, причем индекс состоит из двух столбцов, а не один. Например, одно поле за год, одно за месяц, поле «элемент», которое показывает «элемент 1» и «элемент 2» и поле «значение» с числовыми значениями. Я хочу, чтобы индекс был год + месяц.

Единственный способ, которым мне удалось заставить это работать, – объединить два поля в один, а затем разделить их снова. Есть ли способ лучше?

Минимальный код, скопированный ниже. Большое спасибо!

PS Да, я знаю, что есть другие вопросы с ключевыми словами «поворот» и «мультииндекс», но я не понимал, могут ли они помочь мне в этом вопросе.

import pandas as pd import numpy as np df= pd.DataFrame() month = np.arange(1,13) values1 = np.random.randint(0,100,12) values2 = np.random.randint(200,300,12) df['month'] = np.hstack(( month, month )) df['year']=2004 df['value'] = np.hstack(( values1, values2 )) df['item']= np.hstack(( np.repeat('item 1',12), np.repeat('item 2',12) )) # This doesn't work: ValueError: Wrong number of items passed 24, placement implies 2 # mypiv = df.pivot( ['year', 'month'], 'item' ,'value' ) #This doesn't work, either: #df.set_index(['year', 'month'], inplace=True) # ValueError: cannot label index with a null key #mypiv = df.pivot(columns='item', values='value') #This below works but is not ideal: I have to first concatenate then separate the fields I need df['new field']= df['year'] * 100 + df['month'] mypiv = df.pivot('new field', 'item', 'value').reset_index() mypiv['year'] = mypiv['new field'].apply( lambda x: int(x) / 100) mypiv['month'] = mypiv['new field'] % 100 

Вы можете группировать и затем откладывать.

 >>> df.groupby(['year', 'month', 'item'])['value'].sum().unstack('item') item item 1 item 2 year month 2004 1 33 250 2 44 224 3 41 268 4 29 232 5 57 252 6 61 255 7 28 254 8 15 229 9 29 258 10 49 207 11 36 254 12 23 209 

Или используйте pivot_table :

 >>> df.pivot_table(values='value', index=['year', 'month'], columns='item') item item 1 item 2 year month 2004 1 33 250 2 44 224 3 41 268 4 29 232 5 57 252 6 61 255 7 28 254 8 15 229 9 29 258 10 49 207 11 36 254 12 23 209 

Я считаю, что если вы включили item в свой MultiIndex, тогда вы можете просто расстегнуть:

 df.set_index(['year', 'month', 'item']).unstack(level=-1) 

Это дает:

  value item item 1 item 2 year month 2004 1 21 277 2 43 244 3 12 262 4 80 201 5 22 287 6 52 284 7 90 249 8 14 229 9 52 205 10 76 207 11 88 259 12 90 200 

Это немного быстрее, чем использование pivot_table , и примерно с той же скоростью или немного медленнее, чем использование groupby .