2015-02-24 51 views
0

我创建了一个三级多指标(组,产品和状态)的数据透视表。状态级别按字母顺序自动排序,但我需要将排序更改为自定义的非字母排序。我可能还需要以类似的方式重新订购组和产品级别。熊猫枢轴表 - 多指数reoganize订单

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。但是,各州仍按字母顺序排序。

任何对修复的见解都将非常感谢。

+0

可能是http://stackoverflow.com/questions/26707171/sort-pandas-dataframe-based-on-list – aensm 2015-02-24 16:14:44

+0

的副本上面的文章中的方法对我的DataFrame中的重新排序和显示观察结果非常有效;但是,当我从DataFrame创建数据透视表时,排序会改变。状态,这是在我原来的DataFrame中排序的属性,按字母顺序排序。 – marshackVB 2015-02-25 16:16:33

+0

我相信我需要一种方法来通过提供一个列表专门重新排列数据透视表的多索引级别2(州名),尽管我已经尝试过并且未能完成此任务。 – marshackVB 2015-02-25 16:27:24

回答

1

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

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) 

编辑:仅供参考,类别D型是比较新的。 0.15.0我相信

+0

谢谢你的回复。我仍然无法防止代表状态名称的数据透视表多级索引级别2按字母顺序进行操作。数据透视表基于的DataFrame按状态正确地重新组织。一旦我创建数据透视表,排序就会改变。看起来我需要专门对数据透视表多索引进行重新排序,而不是基于它的DataFrame数据。 – marshackVB 2015-02-25 16:22:35

+0

重置主键索引时会发生什么?它排序正确吗? – 2015-02-25 16:34:22

+0

我试过pivot.reset_index(),但状态依然按照字母顺序排序,因为它们在原始表中。我也尝试使用groupby()和unstack()创建数据透视表。尽管如此,按照字母顺序对状态进行了重新排序,即使在原始的DataFrame中,状态也被归类为分类,并按照上面列出的列表的顺序进行排序。 – marshackVB 2015-02-28 18:12:38

0

我被类似的问题咬了,我会发布样本解决方案。 您可以使用虚拟变量和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中引入的分类变量可能会有更好的方法,但我不知道更简单的解决方案。

+0

谢谢;我会试试这个。 – marshackVB 2015-06-27 17:13:31