这似乎是一个简单的问题,但我找不到任何东西 我有数据帧:
df = pd.DataFrame({'x':[1,3,1,3,1,5,1,5],
'cat1':['A','A','B','B','A','A','B','B'],
'cat2':['A','A','A','A','B','B','B','B']})
cat1 cat2 x
0 A A 1
1 A A 3
2 B A 1
3 B A 3
4 A B 1
5 A B 5
6 B B 1
7 B B 5
cat1和cat 2是某些类别,我想使用一些聚合函数(总和,加权平均值或定义的东西)对它们进行聚合x。显而易见的解决方案,如
res = df.groupby(['cat1','cat2']).sum()
结果
x
cat1 cat2
A A 4
B 6
B A 4
B 6
但我想要的是:
cat1 cat2 x
0 A A 4
1 A B 6
2 A Any 10
3 B A 4
4 B B 6
5 B Any 10
6 Any A 8
7 Any B 12
8 Any Any 20
一种方法是使用类似的东西:
res2 = df.groupby(['cat1','cat2']).sum().reset_index()
res1a = df.groupby(['cat1']).sum().reset_index()
res1b = df.groupby(['cat2']).sum().reset_index()
res1a['cat2'] = 'any'
res1b['cat1'] = 'any'
res = res1a.append(res1b).append(res2).set_index(['cat1','cat2'])
但是由于我的实际任务涉及大约10个类别,因此为各种类别子集创建单独的组块并将它们全部附加在一起并不方便。我希望有更好的方法去
答案 0 :(得分:1)
您可以使用unstack
进行重塑,使用Any
添加新列和新行sum
,然后按stack
重新整形:
#add `['x']` for Series output
res = df.groupby(['cat1','cat2'])['x'].sum()
print (res)
cat1 cat2
A A 4
B 6
B A 4
B 6
Name: x, dtype: int64
a = res.unstack()
a['Any'] = a.sum(axis=1)
a.loc['Any'] = a.sum()
print (a)
cat2 A B Any
cat1
A 4 6 10
B 4 6 10
Any 8 12 20
df1 = a.stack()
print (df1)
cat1 cat2
A A 4
B 6
Any 10
B A 4
B 6
Any 10
Any A 8
B 12
Any 20
dtype: int64
编辑:
res2 = df.groupby(['cat1','cat2']).sum()
res1a = df.groupby(['cat1']).sum()
res1b = df.groupby(['cat2']).sum()
res1a = res1a.set_index(pd.Series(['any'] * len(res1a), name='cat2'), append=True)
res1b=res1b.set_index(pd.Series(['any'] * len(res1b), name='cat1'), append=True).swaplevel()
res1ab=pd.DataFrame(res1a.sum().values,
index=pd.MultiIndex.from_arrays([['any'],['any']]),
columns=['x'])
res2 = pd.concat([res2, res1a, res1b, res1ab])
print (res2)
x
cat1 cat2
A A 4
B 6
B A 4
B 6
A any 10
B any 10
any A 8
B 12
any 20