按第二列排序,按组计算累计和并追加到原数据框
我有一个包含两列的表格,里面有多个组。第一列是组名,第二列是日期,这些日期需要按正确的顺序排列。我想要对第一列中每个独特的组,按照第二列的顺序进行累加求和,得到一个第三列的结果。
我还没找到一个简单优雅的方法来实现这个目标。下面的代码可以完成这个任务,但它会对整个表格进行求和,而且非常依赖于正确的排序。
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