2015-02-24 77 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