在Python Pandas中使用cumsum with groupby并在value为0时重置cumsum

时间:2016-09-28 07:46:42

标签: python-3.x pandas group-by cumsum

我是python的新手。 我尝试为每个客户提供累积金额,以查看相应的几个月不活动状态(标记:1或0)。因此,当我们有一个0时,需要重置1的累积和。当我们有一个新的客户端时,重置也需要发生。请参见下面的示例,其中a是客户列,b是日期。

经过一些研究,我发现问题'Cumsum在NaN重置'和'在Python中使用cumsum with groupby'。我认为我有点需要把它们组合在一起。 将“CUMum重置为NaN”的代码调整为重置为0,成功:

cumsum = v.cumsum().fillna(method='pad')
reset = -cumsum[v.isnull() !=0].diff().fillna(cumsum)
result = v.where(v.notnull(), reset).cumsum()

但是,我没有成功添加groupby。我的计数继续......

因此,数据集将如下所示: 将pandas导入为pd

df =  pd.DataFrame({'a' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2], 
                    'b' : [1/15,2/15,3/15,4/15,5/15,6/15,1/15,2/15,3/15,4/15,5/15,6/15], 
                    'c' : [1,0,1,0,1,1,0,1,1,0,1,1,1,1]})

这应该会产生一个带有a,b,c和d列

的数据框
'd' : [1,0,1,0,1,2,0,1,2,0,1,2,3,4]

请注意,我有一个非常大的数据集,因此计算时间非常重要。

感谢您帮助我

2 个答案:

答案 0 :(得分:4)

在组中查找连续值后,使用groupby.applycumsum。然后groupby.cumcount得到整数计数到每个连续值并稍后加1。

与原始行相乘以创建AND逻辑,取消全零并仅考虑正值。

run(SKAction.afterDelay(5, runBlock: {
    self.paddleRTouched = false
}))

另一种方法是在series.expanding之后对groupby对象应用一个函数,它基本上计算从第一个索引到当前索引的系列值。

稍后使用df['d'] = df.groupby('a')['c'] \ .apply(lambda x: x * (x.groupby((x != x.shift()).cumsum()).cumcount() + 1)) print(df['d']) 0 1 1 0 2 1 3 0 4 1 5 2 6 0 7 1 8 2 9 0 10 1 11 2 12 3 13 4 Name: d, dtype: int64 将两个args的函数累加应用于iterable项,以便将其减少为单个值。

reduce

<强>时序:

from functools import reduce

df.groupby('a')['c'].expanding()                                         \
  .apply(lambda i: reduce(lambda x, y: x+1 if y==1 else 0, i, 0))

a    
1  0     1.0
   1     0.0
   2     1.0
   3     0.0
   4     1.0
   5     2.0
   6     0.0
2  7     1.0
   8     2.0
   9     0.0
   10    1.0
   11    2.0
   12    3.0
   13    4.0
Name: c, dtype: float64

答案 1 :(得分:2)

我认为您需要使用groupby自定义功能:

#change row with index 6 to 1 for better testing
df =  pd.DataFrame({'a' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2], 
                    'b' : [1/15,2/15,3/15,4/15,5/15,6/15,1/15,2/15,3/15,4/15,5/15,6/15,7/15,8/15], 
                    'c' : [1,0,1,0,1,1,1,1,1,0,1,1,1,1],
                    'd' : [1,0,1,0,1,2,3,1,2,0,1,2,3,4]})

print (df)
    a         b  c  d
0   1  0.066667  1  1
1   1  0.133333  0  0
2   1  0.200000  1  1
3   1  0.266667  0  0
4   1  0.333333  1  1
5   1  0.400000  1  2
6   1  0.066667  1  3
7   2  0.133333  1  1
8   2  0.200000  1  2
9   2  0.266667  0  0
10  2  0.333333  1  1
11  2  0.400000  1  2
12  2  0.466667  1  3
13  2  0.533333  1  4
def f(x):
    x.ix[x.c == 1, 'e'] = 1
    a = x.e.notnull()
    x.e = a.cumsum()-a.cumsum().where(~a).ffill().fillna(0).astype(int)
    return (x)

print (df.groupby('a').apply(f))
    a         b  c  d  e
0   1  0.066667  1  1  1
1   1  0.133333  0  0  0
2   1  0.200000  1  1  1
3   1  0.266667  0  0  0
4   1  0.333333  1  1  1
5   1  0.400000  1  2  2
6   1  0.066667  1  3  3
7   2  0.133333  1  1  1
8   2  0.200000  1  2  2
9   2  0.266667  0  0  0
10  2  0.333333  1  1  1
11  2  0.400000  1  2  2
12  2  0.466667  1  3  3
13  2  0.533333  1  4  4