我有以下数据框:
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
我想对第一级(级别= 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))
但是我出错了。
谢谢您的建议。
答案 0 :(得分: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
答案 1 :(得分: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