pandas:如何使用多索引运行数据透视?

Pyt*_*ous 40 python pivot multi-index pandas

我想在熊猫上运行一个轴DataFrame,索引是两列,而不是一列.例如,年份的一个字段,月份的一个字段,显示"项目1"和"项目2"的"项目"字段和带有数值的"值"字段.我希望索引是年+月.

我设法让这个工作的唯一方法是将两个字段合并为一个,然后再将它们分开.有没有更好的办法?

下面复制的最小代码.非常感谢!

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
Run Code Online (Sandbox Code Playgroud)

Ale*_*der 60

您可以分组然后取消堆叠.

>>> 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
Run Code Online (Sandbox Code Playgroud)

或使用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
Run Code Online (Sandbox Code Playgroud)

  • @Alexander,`pivot_table()`需要_aggfunc_参数,如果没有提供这样的参数,则默认使用`mean()`函数.如果需要`sum()`功能,那么`pivot_table()`函数应该在调用中添加`aggfunc = sum`.**来源:**[pandas文档](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.pivot_table.html#pandas.DataFrame.pivot_table)_aggfunc:函数,函数列表,dict,默认numpy.mean_ (2认同)

Aje*_*ean 24

我相信如果你包含item在你的MultiIndex中,那么你可以只是取消堆栈:

df.set_index(['year', 'month', 'item']).unstack(level=-1)
Run Code Online (Sandbox Code Playgroud)

这会产生:

                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
Run Code Online (Sandbox Code Playgroud)

它比使用速度快一点pivot_table,速度与使用速度相同或稍慢groupby.