在pandas中使用cumsum on group()

mst*_*een 12 python group-by pandas

来自熊猫新手:我的数据看起来基本上是这样的 -

 data1=pd.DataFrame({'Dir':['E','E','W','W','E','W','W','E'], 'Bool':['Y','N','Y','N','Y','N','Y','N'], 'Data':[4,5,6,7,8,9,10,11]}, index=pd.DatetimeIndex(['12/30/2000','12/30/2000','12/30/2000','1/2/2001','1/3/2001','1/3/2001','12/30/2000','12/30/2000']))
data1
Out[1]: 
           Bool  Data Dir
2000-12-30    Y     4   E
2000-12-30    N     5   E
2000-12-30    Y     6   W
2001-01-02    N     7   W
2001-01-03    Y     8   E
2001-01-03    N     9   W
2000-12-30    Y    10   W
2000-12-30    N    11   E
Run Code Online (Sandbox Code Playgroud)

我希望将它分组为多个级别,然后执行cumsum():

例如,像running_sum=data1.groupby(['Bool','Dir']).cumsum()< - (不起作用)

输出看起来像:

Bool Dir Date        running_sum
N    E   2000-12-30           16
     W   2001-01-02            7
         2001-01-03           16
Y    E   2000-12-30            4
         2001-01-03           12
     W   2000-12-30           16
Run Code Online (Sandbox Code Playgroud)

我的"喜欢"代码显然不是很接近.我做了很多尝试,并学到了很多关于如何不这样做的新事物.

谢谢你提供的所有帮助.

bdi*_*nte 14

试试这个:

data2 = data1.reset_index()
data3 = data2.set_index(["Bool", "Dir", "index"])   # index is the new column created by reset_index
running_sum = data3.groupby(level=[0,1,2]).sum().groupby(level=[0,1]).cumsum()
Run Code Online (Sandbox Code Playgroud)

你不能简单地使用的原因cumsumdata3与您的数据是如何组织的事情.通过Bool和分组Dir 并应用聚合函数(sum,mean等)会生成比您开始时更小的DataFrame,因为您使用的任何函数都会根据您的组键聚合值.但是cumsum不是聚合功能.它将返回一个与它所调用的大小相同的DataFrame.因此,除非您的输入DataFrame采用调用后输出大小相同的格式cumsum,否则将引发错误.这就是我sum首先调用的原因,它以正确的输入格式返回DataFrame.

对不起,如果我没有解释得这么好.也许其他人可以帮助我?


Mal*_*ina 9

正如另一个答案所指出的那样,你试图将相同的日期折叠成单行,而cumsum函数将返回一系列与原始DataFrame相同的长度.换句话说,您实际上想要按[Bool,Dir,Date]进行分组,计算每个组中的总和,然后返回按[Bool,Dir]分组的行的cumsum.另一个答案是对您的具体问题的完全有效的解决方案,这是一个单行的变化:

data1.groupby(['Bool', 'Dir', 'Date']).sum().groupby(level=[0, 1]).cumsum()
Run Code Online (Sandbox Code Playgroud)

这将以请求的格式完全返回输出.

对于那些在Pandas组中寻找简单的cumsum的人,您可以使用:

data1.groupby(['Bool', 'Dir']).apply(lambda x: x['Data'].cumsum())
Run Code Online (Sandbox Code Playgroud)

累积总和在每个组内部计算.这是输出的样子:

Bool  Dir            
N     E    2000-12-30     5
           2000-12-30    16
      W    2001-01-02     7
           2001-01-03    16
Y     E    2000-12-30     4
           2001-01-03    12
      W    2000-12-30     6
           2000-12-30    16
Name: Data, dtype: int64
Run Code Online (Sandbox Code Playgroud)

请注意重复的日期,但这是在Bool和Dir列标识的每个组的行内部执行严格的累积和.