如何在pandas中对特定层级的列进行求和?

3

I have following dataframe:

import pandas as pd
df = pd.DataFrame(data=[[1,2,3,4,5,6,1,2,3], [7,8,9,10,11,12,7,8,9], [13,14,15,16,17,18,4,5,6]], index=pd.date_range('2004-01-01', '2004-01-03'))
df.columns = pd.MultiIndex.from_product([['x', 'y', 'z'], list('abc')])

df
                 x           y          z      
             a   b   c   a   b   c  a  b  c
2004-01-01   1   2   3   4   5   6  1  2  3
2004-01-02   7   8   9  10  11  12  7  8  9
2004-01-03  13  14  15  16  17  18  4  5  6

我想在第一层级(level=0)对列进行分组求和,希望得到以下结果:

                (x+z)           y      
             a   b   c   a   b   c
2004-01-01   2   4   6   4   5   6
2004-01-02  14  16  18  10  11  12
2004-01-03  17  19  21  16  17  18

我尝试过的:

mapping = {'x': 'r1', 'y': 'r2', 'z': 'r1'}
df.groupby(mapping, axis=1, level=0).apply(lambda g: g.sum(axis=1, level=1))

但我遇到了一个错误。
感谢任何建议。
2个回答

2

如果较低级别的键相同,将两个级别求和很简单。您可以先求和再连接:

最初的回答:

只要较低级别的键相同,将两个级别求和就很简单。你可以先求和再拼接:

pd.concat([df['x'] + df['z'], df['y']], keys=['(x+z)', 'y'], axis=1)

           (x+z)           y        
               a   b   c   a   b   c
2004-01-01     2   4   6   4   5   6
2004-01-02    14  16  18  10  11  12
2004-01-03    17  19  21  16  17  18

不要忘记将结果赋值给一个变量。


如果您需要对任意数量的值进行求和,请使用pd.IndexSlice进行切片并使用sum函数:

cols_to_sum = ['x', 'y']
sums = df.loc[:, pd.IndexSlice[cols_to_sum]].sum(level=1, axis=1)
sums.columns = pd.MultiIndex.from_product([['+'.join(cols_to_sum)], sums.columns])
sums

           x+y        
             a   b   c
2004-01-01   5   7   9
2004-01-02  17  19  21
2004-01-03  29  31  33

要将其串联起来,请像往常一样使用concat。最初的回答。
pd.concat([sums, df.drop(cols_to_sum, axis=1, level=0)], axis=1)

           x+y          z      
             a   b   c  a  b  c
2004-01-01   5   7   9  1  2  3
2004-01-02  17  19  21  7  8  9
2004-01-03  29  31  33  4  5  6

2
可以使用map函数将第一级映射成一个新的MultiIndex来进行分组。这将会使得MultiIndex被压缩为元组,所以我们需要重新设置它。"最初的回答"
d = {'x': 'r1', 'y': 'r2', 'z': 'r1'}
idx = pd.MultiIndex.from_tuples([(d.get(x, x), y) for x, y in df.columns])

df1 = df.groupby(idx, axis=1).sum()
df1.columns = pd.MultiIndex.from_tuples(df1.columns)

            r1          r2        
             a   b   c   a   b   c
2004-01-01   2   4   6   4   5   6
2004-01-02  14  16  18  10  11  12
2004-01-03  17  19  21  16  17  18

1
代码的第二行可以稍作改进:不要直接访问字典"d[x]",而是使用"d.get(x, x)"。这样就不必在字典中指定未映射的列了。 - binaryEcon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接