2016-04-24 123 views
-1

我想爲索引#1(即水果和動物)和列的小計列(即2015和2016)添加小計行。大熊貓數據透視表索引和列的小計

對於小計列,我可以做這樣的事情,但是對於每年運行這種類型的代碼似乎效率不高(2015 & 2016)。有沒有更好的辦法?我不認爲'利潤率'會起作用,因爲有多個小計。

df[('2015','2015_Total')] = df[('2015','1st')]+df[('2015','2nd')] 

對於小計行(例如,水果總數和動物總數),我不確定從哪裏開始。

enter image description here

+0

你能否能夠添加一段代碼來生成數據幀,達到高達你需要幫助的點? – Abbas

回答

1

這是非常複雜的,因爲你需要在columnsindex創建Multiindex

創建小計很容易 - 使用groupbysum。然後創建Multiindex並將concat新列更改爲原始DataFrame。最後,你必須sort_index(I值前添加Total_正確排序):

print df 
       2015_____  2016_______  
        1st 2nd   1st 2nd 
Fruits Apple   10 9   11 10 
     Banana  20 22   21 20 
Animal Lion   5 3   2 1 
     Tiger   2 3   5 0 

df1 = df.groupby(level=0, axis=1).sum() 
print df1 
       2015_____ 2016_______ 
Fruits Apple   19   21 
     Banana   42   41 
Animal Lion   8   3 
     Tiger   5   5 

print df.columns.get_level_values(0).to_series().drop_duplicates().tolist() 
['2015_____', '2016_______'] 

#change index to multiindex 
new_columns = zip(df.columns.get_level_values(0).to_series().drop_duplicates().tolist(), 
        "Total_" + df1.columns.str[:4]) 
print new_columns 
[('2015_____', 'Total_2015'), ('2016_______', 'Total_2016')] 

df1.columns = pd.MultiIndex.from_tuples(new_columns) 
print df1 
       2015_____ 2016_______ 
       Total_2015 Total_2016 
Fruits Apple   19   21 
     Banana   42   41 
Animal Lion   8   3 
     Tiger   5   5 

df = pd.concat([df,df1], axis=1) 
df2 = df.groupby(level=0, sort=False).sum() 
print df2 
     2015_____  2016_______  2015_____ 2016_______ 
      1st 2nd   1st 2nd Total_2015 Total_2016 
Animal   7 6   7 1   13   8 
Fruits  30 31   32 30   61   62 

print df.index.levels[0][df.columns.labels[0]].to_series().drop_duplicates().tolist() 
['Animal', 'Fruits'] 

#change index to multiindex 
new_idx=zip(df.index.levels[0][df.columns.labels[0]].to_series().drop_duplicates().tolist(), 
      "Total_" + df2.index) 
print new_idx 
[('Animal', 'Total_Animal'), ('Fruits', 'Total_Fruits')] 

df2.index = pd.MultiIndex.from_tuples(new_idx) 
print df2 
        2015_____  2016_______  2015_____ 2016_______ 
          1st 2nd   1st 2nd Total_2015 Total_2016 
Animal Total_Animal   7 6   7 1   13   8 
Fruits Total_Fruits  30 31   32 30   61   62 

df = pd.concat([df,df2]) 
df = df.sort_index(axis=1).sort_index() 
print df 
        2015_____    2016_______    
          1st 2nd Total_2015   1st 2nd Total_2016 
Animal Lion     5 3   8   2 1   3 
     Tiger    2 3   5   5 0   5 
     Total_Animal   7 6   13   7 1   8 
Fruits Apple    10 9   19   11 10   21 
     Banana    20 22   42   21 20   41 
     Total_Fruits  30 31   61   32 30   62 
+0

謝謝!我認爲你不是有意要在new_idx = zip(df.index.levels [0] [df.columns.labels [0]]中包含df.columns.labels [0] ...,對嗎? –

+0

是的,我我認爲你也可以在列中使用它,我必須使用這種方法,因爲有問題 - 列表的值被交換了。Btw,[解決方案也使用標籤](http://stackoverflow.com/questions/14189695) /復位指數換數據幀列)。 – jezrael