【问题标题】:Subtotals for Pandas pivot table index and columnPandas 数据透视表索引和列的小计
【发布时间】:2016-04-24 17:30:11
【问题描述】:

我想为索引 #1(即 Fruits 和 Animal)添加小计行,并为列(即 2015 年和 2016 年)添加小计列。

对于小计列,我可以这样做,但每年(2015 年和 2016 年)运行这种类型的代码似乎效率低下。有没有更好的办法?我不认为“边距”会起作用,因为有多个小计。

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

对于小计行(例如,水果总数和动物总数),我不知道从哪里开始。

【问题讨论】:

  • 您能否添加一段代码来生成数据框并达到您需要帮助的程度?

标签: python pandas


【解决方案1】:

这很复杂,因为你需要在columnsindex中创建Multiindex

创建小计很容易 - 使用 groupbysum。然后创建多索引并将concat 新列添加到原始DataFrame。最后你必须sort_index(我在正确排序值之前添加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

【讨论】:

  • 谢谢!!!!我认为您并不是要在 new_idx=zip(df.index.levels[0][df.columns.labels[0]] 中包含 df.columns.labels[0]... ,对吧?
  • 是的,我认为您也可以将它用于列。我必须使用这种方法,因为存在问题 - 列表的值被交换了。顺便说一句,solution which use labels with levels too.
  • 对我的问题进行了一些调整,这个答案对我帮助很大!
猜你喜欢
  • 2020-10-17
  • 2021-11-03
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 2017-05-13
  • 2020-08-30
  • 2019-04-07
相关资源
最近更新 更多