Pandas Pivot Table - 重新组织多索引的顺序

Posted

技术标签:

【中文标题】Pandas Pivot Table - 重新组织多索引的顺序【英文标题】:Pandas Pivot Table - reoganize order of multi-index 【发布时间】:2015-04-25 12:01:18 【问题描述】:

我创建了一个包含三级多索引(组、产品和状态)的数据透视表。状态级别自动按字母顺序排序,但我需要将排序更改为自定义的非字母排序。我可能还需要以类似方式重新排序 Group 和 Product 级别。

pivot = data.pivot_table(rows=['Group', 'Product', 'State'], 
                     values = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 
                               'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 
                               'NOV', 'DEC'], fill_value=0, margins=True aggfunc=sum) 

cols = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']

#I used this method to prevent the month names from being alphabetically sorted 
pivot = pivot[cols]

数据透视表的一部分如下所示...

                                 JUN     JUL    AUG
Group    Product     State   
Group A  Product A   AZ          0       0      0
                     CO          0       0      0
                     GA          0       0      0
                     IL          0       0      0
                     IN          0       0      0
                     KS          0       0      0
                     MN          0       0      0
                     MO          0       0      0

我需要状态的顺序如下...

state_order = ['AZ','CO','ID','NV','OR','UT','WA','IA','KS','MN','MO','NE','ND','SD','GA','IL','IN','OH','WI']

我尝试了 reindex_axis() 函数,输入上面的列表并指定 level=2。但是,这些州仍然按字母顺序排序。

我们将不胜感激任何有关修复的见解。

【问题讨论】:

可能与***.com/questions/26707171/…重复 上面帖子中的方法非常适合在我的 DataFrame 中重新排序和显示观察结果;但是,当我从 DataFrame 创建数据透视表时,顺序发生了变化。在我的原始 DataFrame 中对属性进行排序的状态按字母顺序排列。 我相信我需要一种方法来通过提供一个列表来专门重新排序数据透视表的多索引级别 2(状态名称),尽管我已经尝试过但未能做到这一点。 【参考方案1】:

我被类似的问题所困扰,我将发布一个示例解决方案。 您可以使用虚拟变量和 groupby。

import pandas as pd 
import numpy as np 

index = pd.MultiIndex.from_tuples(zip(['a', 'a', 'a', 'b', 'b', 'b'],
                                      [0, 0, 0, 1, 1, 1],
                                      ['x', 'xx', 'xxx', 'x', 'xx', 'xxx']),
                                      names=['A', 'B', 'C'])
df = pd.DataFrame(np.random.rand(6, 3), index = index)
>>> df
                0         1         2
A B C                                
a 0 x    0.839870  0.763803  0.847632
    xx   0.619066  0.715492  0.467518
    xxx  0.917468  0.923521  0.278665
b 1 x    0.660889  0.209247  0.502107
    xx   0.069925  0.889308  0.836755
    xxx  0.967187  0.650482  0.138759



desired_order = ['xxx', 'xx', 'x']
df = df.reset_index(2)
mapping =  _ : desired_order.index(_) for _ in df['C'] 

df['Dummy'] = df['C'].map(lambda x: mapping[x]) #gives desired order
df = df.groupby(level=['A', 'B']).apply(lambda x: x.sort('Dummy'))
df.drop('Dummy', axis=1)


>>> df 
       C         0         1         2
A B                                   
a 0  xxx  0.273731  0.561262  0.970034
  0   xx  0.859063  0.459765  0.921475
  0    x  0.640554  0.045410  0.512320
b 1  xxx  0.678473  0.380712  0.252676
  1   xx  0.501426  0.577250  0.317702
  1    x  0.586227  0.927453  0.794912

可能有更好的方法使用 pandas 0.15 中引入的分类变量,但我不知道更简单的解决方案。

【讨论】:

谢谢;我会试试看。【参考方案2】:

您可以尝试将State的数据类型更改为类别。

data["state"] = data["state"].astype("category")

然后设置排序顺序

data["state"].cat.set_categories(['AZ','CO','ID','NV','OR','UT','WA','IA','KS',
                  'MN','MO','NE','ND','SD','GA','IL','IN','OH','WI'],inplace=True)

编辑:仅供参考,类别 dtype 相对较新。 0.15.0 我相信

【讨论】:

感谢您的回复。我仍然无法阻止代表州名的数据透视表多索引级别 2 按字母顺序排列。数据透视表所基于的 DataFrame 已按状态正确重组。一旦我创建了数据透视表,顺序就会改变。看来我需要专门重新排序数据透视表多索引,而不是它所基于的DataFrame数据。 重置pivot的索引会发生什么?是否正确排序? 我尝试了 pivot.reset_index() 但状态仍然按字母顺序排序,就像它们在原始表中一样。我还尝试使用 groupby() 和 unstack() 创建数据透视表。尽管如此,状态还是按字母顺序重新排序,即使在原始 DataFrame 中,状态被归类为分类状态并按照我上面提供的列表的顺序进行排序。 我将不胜感激任何其他建议。感谢您的帮助。 抱歉,我没有更多的想法。您可以尝试用不同的标题再次提问,看看是否有其他人可以提供帮助。

以上是关于Pandas Pivot Table - 重新组织多索引的顺序的主要内容,如果未能解决你的问题,请参考以下文章

Pandas 透视表pivot_table详解

图解Pandas透视表pivot_table

pandas 透视表 pivot_table

如何在 pandas 的 crosstab/pivot_table 中使用两个不同的函数?

使用 pivot_table 将一列 dict 聚合到一个 dict 列表中 - Pandas

2018.03.29 python-pandas 数据透视pivot table / 交叉表crosstab