我注意到,当我们groupby
一个dataframe
& sum
时,我们得到一个完整的dataframe
作为回报:
dict1 = {'A': {0: 'A0', 1: 'A0', 2: 'A0', 3: 'A0', 4: 'A1', 5: 'A1', 6: 'A1', 7: 'A1', 8: 'A1', 9: 'A1'}, 'B': {0: 'B0', 1: 'B1', 2: 'B2', 3: 'B3', 4: 'B4', 5: 'B5', 6: 'B6', 7: 'B7', 8: 'B8', 9: 'B9'}, 'C': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}, 'D': {0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15, 6: 16, 7: 17, 8: 18, 9: 19}, 'E': {0: 'E0', 1: 'E1', 2: 'E0', 3: 'E1', 4: 'E0', 5: 'E1', 6: 'E0', 7: 'E1', 8: 'E0', 9: 'E1'}}
df2 = pd.DataFrame(dict1)
A E
A0 E0 22
E1 24
A1 E0 48
E1 51
Name: D, dtype: int64
但是当我执行cumsum
时,它只返回结果累积序列。为什么它们的行为不同?我如何使cumsum
与分组的dataframe
一起返回,而不将其赋值回去?
一个二个一个一个
- 编辑:**我原以为这是一个简单的解决方法,我可以处理剩下的问题。但根据你目前的评论,这让我偏离了我的最终目标。我希望最终实现一组多个变量的总和、平均值、累计值--如下所示:
df2.groupby(['A','E']).agg({'D':'cumsum','C':lambda x: 4*np.sum(x)})
但它会给出如下输出:
D C
0 10.0 NaN
1 11.0 NaN
2 22.0 NaN
3 24.0 NaN
4 14.0 NaN
5 15.0 NaN
6 30.0 NaN
7 32.0 NaN
8 48.0 NaN
9 51.0 NaN
(A0, E0) NaN 8.0
(A0, E1) NaN 16.0
(A1, E0) NaN 72.0
(A1, E1) NaN 84.0
那么,有没有一种方法可以在不单独处理累积和的情况下实现呢?
1条答案
按热度按时间a64a0gku1#
基于你在两个脚本中已经看到的行为,很容易理解这一点。
pd.Series.cumsum()
为每个组返回与列D
相同长度的另一个序列,而你的lambda函数为每个组返回一个值,这导致返回的索引不同。您所要做的就是使用另一个lambda函数来捕获每个组级别上的完整cumsum操作,这个lambda函数返回一个列表对象作为聚合,而不是一个系列输出作为转换。
这将返回由A列和E列组成的组级别的 Dataframe 。
但是,如果您希望 Dataframe 具有与原始 Dataframe 相同的索引,则只需
explode
新列D
即可一个二个一个一个
sum
是一个聚合,为每个组返回一个值(float/int),而cumsum
是一个转换,返回一个与输入行数相同的序列。cumsum
基本上转换给定的输入序列(每组D列的行)并返回另一个序列。sum
返回带有索引的序列作为答案中的第一个脚本,cumsum
返回索引作为答案中的第二个脚本。当Pandas试图协调它们时,它会堆叠索引,因为它们不匹配。cumsum
,返回具有3个值[14,30,48]的序列,而sum
返回值72的聚合transform
进行编码**如果你想避免使用lambda函数,正如我从你的评论中所理解的,你可以在groupby对象上使用
transform
方法,但是这不允许同时为不同的列传递多个转换作为一个dict,所以你仍然需要重新分配这些列。