pandas DataFrame
でピボットを実行したいのですが、インデックスは1列ではなく2列です。たとえば、年に1つのフィールド、月に1つのフィールド、「item 1」および「item 2」を表示する「item」フィールド、および数値を含む「value」フィールド。インデックスを年+月にしたい。
これを機能させる唯一の方法は、2つのフィールドを1つに結合してから、それらを再び分離することでした。より良い方法はありますか?
以下にコピーした最小限のコード。どうもありがとう!
PSはい、キーワード 'pivot'および 'multi-index'に関して他の質問があることは承知していますが、この質問でそれらが私を助けることができるかどうか/どのように役立つか理解できませんでした。
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',
aggfunc=np.sum)
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
MultiIndexにitem
を含めると、単にスタックを解除できると思います。
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
を使用するよりもほぼ同じ速度またはわずかに遅いです。