我想对DataFrame
进行分组,然后应用多个列的函数返回单个结果。
In [25]: length = 100
In [26]: rnd = np.random.random
In [27]: df = pd.DataFrame(dict(group=np.random.choice(['a','b','c'], length), foo=rnd(length), bar=rnd(length)))
In [28]: df.head()
Out[28]:
bar foo group
0 0.068853 0.201808 a
1 0.148494 0.722194 c
2 0.902275 0.865231 b
3 0.933513 0.843651 a
4 0.910224 0.671588 a
但是,如果我执行了aggregate
,我会将结果返回两次(GroupBy
后每个剩余列一次。)我做错了什么?
In [29]: df.groupby('group').agg(lambda g: sum(g.bar + g.foo))
Out[29]:
bar foo
group
a 36.937812 36.937812
b 33.021105 33.021105
c 30.274639 30.274639
我真正想要的只是Series
,结果与Out[29]
相同。
答案 0 :(得分:3)
我认为这是因为agg
倾向于保持与原始群组相同的ndim
,而不是将群组从ndim=2
挤压到ndim=1
。这就是说,你的子组是nx2 ndarray
,计算确实返回一个标量,然后它以1x2广播到非压缩ndarray
(所以它仍然是2 d数组与原始列)。或者,换句话说,规则agg
是在axis=0
之间聚合子组数据帧(nx2),因此返回的形状必须为1x2。因此,即使您获得了标量结果,当.agg
返回结果时,它也会被广播为1x2。
可以使用apply
而不是agg
修复此问题,因为apply
对返回的形状没有约束。
df.groupby('group').apply(lambda g: sum(g.bar + g.foo))
group
a 39.4419
b 27.2982
c 25.3910
dtype: float64
答案 1 :(得分:1)
如果你不介意按步骤做,为什么不这样做:
In [52]:
df = df.groupby('group').sum()
df['foobar']=df.foo + df.bar
new_series = df.loc[:,'foobar']
new_series
Out[52]:
group
a 33.047944
b 30.503071
c 30.899891
Name: foobar, dtype: float64
In [53]:
type(new_series)
Out[53]:
pandas.core.series.Series