按第二列排序,按组计算累计和并追加到原数据框

5 投票
1 回答
5328 浏览
提问于 2025-04-18 09:58

我有一个包含两列的表格,里面有多个组。第一列是组名,第二列是日期,这些日期需要按正确的顺序排列。我想要对第一列中每个独特的组,按照第二列的顺序进行累加求和,得到一个第三列的结果。

我还没找到一个简单优雅的方法来实现这个目标。下面的代码可以完成这个任务,但它会对整个表格进行求和,而且非常依赖于正确的排序。

multidf = df.groupby(by=['col1','col2']).sum().groupby(level=[0]).cumsum() 这个方法会给出一个分层索引的结果,但我找不到办法把得到的累加和列附加回原来的表格,而不需要进行多步合并。使用reset_index命令只是把表格恢复到原来的状态。

我在寻找一种更好的方法来达到想要的结果。我尝试过lambda、apply和aggregate命令,但总是无法成功。

In[229]: df#example dataframe
Out[229]: 
  col1                 col2  col3
0    a  2013/01/03 00:00:00     1
1    a  2013/03/05 09:43:31     3
2    b  2013/03/07 00:00:00     4
3    b  2013/03/07 00:00:00     2
4    a  2013/03/07 00:00:00     0

import numpy as np
import pandas as pd
##example dataframe
df = pd.DataFrame({'col1' : ['a','a','b','b','a'],
               'col2' : ['2013/01/03 00:00:00', '2013/03/05 09:43:31', '2013/03/07 00:00:00',\
                         '2013/03/07 00:00:00', '2013/03/07 00:00:00'],
               'col3' : [1,3,4,2,0]})
df = df.sort(['col1','col2'])
jj= df.groupby(by = ['col1'],sort=['col1','col2']).cumsum()

df = df.sort(['col1','col2'])

##multi alternative, can't get result back into original df elegantly
multidf = df.groupby(by=['col1','col2']).sum().groupby(level=[0]).cumsum()

df['cumsum'] = jj['col3']
In[227]: df ## result of unelegant method, desired output though how else can i achieve this?
Out[227]: 
  col1                 col2  col3 cumsum
0    a  2013/01/03 00:00:00     1      1
1    a  2013/03/05 09:43:31     3      4
4    a  2013/03/07 00:00:00     0      4
2    b  2013/03/07 00:00:00     4      4
3    b  2013/03/07 00:00:00     2      6

1 个回答

4

把你想要排序的那一列设置为索引会更简单。然后可以使用 groupby.transform(pd.Series.cumsum)。具体可以看下面的代码:

In [1]: df
Out[1]: 
  col1                 col2  col3
0    a  2013/01/03 00:00:00     1
1    a  2013/03/05 09:43:31     3
2    b  2013/03/07 00:00:00     4
3    b  2013/03/07 00:00:00     2
4    a  2013/03/07 00:00:00     0

In [2]: df1=df.set_index('col2').sort_index()
In [3]: df1
Out[3]: 
                    col1  col3
col2                          
2013/01/03 00:00:00    a     1
2013/03/05 09:43:31    a     3
2013/03/07 00:00:00    b     4
2013/03/07 00:00:00    b     2
2013/03/07 00:00:00    a     0


In [4]: df1['cumsum']=df1.groupby('col1')['col3'].transform(pd.Series.cumsum)

In [5]: df1
Out[5]: 
                    col1  col3  cumsum
col2                                  
2013/01/03 00:00:00    a     1       1
2013/03/05 09:43:31    a     3       4
2013/03/07 00:00:00    b     4       4
2013/03/07 00:00:00    b     2       6
2013/03/07 00:00:00    a     0       4

撰写回答