2014-05-23 67 views
3

我有一个数据框,其中每个id记录1个或多个事件。对于每个事件,记录ID,度量x和日期。事情是这样的:大熊猫时间累积总和按组

import pandas as pd 
import datetime as dt 
import numpy as np 
x = range(0, 6) 
id = ['a', 'a', 'b', 'a', 'b', 'b'] 
dates = [dt.datetime(2012, 5, 2),dt.datetime(2012, 4, 2),dt.datetime(2012, 6, 2), 
     dt.datetime(2012, 7, 30),dt.datetime(2012, 4, 1),dt.datetime(2012, 5, 9)] 

df =pd.DataFrame(np.column_stack((id,x,dates)), columns = ['id', 'x', 'dates']) 

我希望能够在数据集中设置的回溯期(即70天)和计算,对于每一行,x的累计总和为ID前述任一事件并且在期望的回顾(不包括用于执行计算的行的x)内。 应该结束了看起来像:

id x    dates want 
0 a 0 2012-05-02 00:00:00 1 
1 a 1 2012-04-02 00:00:00 0 
2 b 2 2012-06-02 00:00:00 9 
3 a 3 2012-07-30 00:00:00 0 
4 b 4 2012-04-01 00:00:00 0 
5 b 5 2012-05-09 00:00:00 4 

回答

1

嗯,一种方法是以下几点:(1)做“身份证”作为分组变量groupby/apply。 (2)在适用范围内,resample该组以每日时间序列。 (3)然后,只需使用rolling_sum(并进行移位,使其不包含当前行的'x'值)来计算70天回溯期的总和。 (4)降低集团回只有原来的意见:

In [12]: df = df.sort(['id','dates']) 
In [13]: df 
Out[13]: 
    id x  dates 
1 a 1 2012-04-02 
0 a 0 2012-05-02 
3 a 3 2012-07-30 
4 b 4 2012-04-01 
5 b 5 2012-05-09 
2 b 2 2012-06-02 

您将需要通过['id','dates']分类数据。现在,我们可以做groupby/apply

In [15]: def past70(g): 
      g = g.set_index('dates').resample('D','last') 
      g['want'] = pd.rolling_sum(g['x'],70,0).shift(1) 
      return g[g.x.notnull()]    

In [16]: df = df.groupby('id').apply(past70).drop('id',axis=1) 
In [17]: df 
Out[17]: 
       x want 
id dates    
a 2012-04-02 1 NaN 
    2012-05-02 0  1 
    2012-07-30 3  0 
b 2012-04-01 4 NaN 
    2012-05-09 5  4 
    2012-06-02 2  9 

如果你不想让NaN的然后就去做:

In [28]: df.fillna(0) 
Out[28]: 
       x want 
id dates    
a 2012-04-02 1  0 
    2012-05-02 0  1 
    2012-07-30 3  0 
b 2012-04-01 4  0 
    2012-05-09 5  4 
    2012-06-02 2  9 

编辑:如果你想在回溯参数做类似如下:

def past_window(g,win=70): 
    g = g.set_index('dates').resample('D','last') 
    g['want'] = pd.rolling_sum(g['x'],win,0).shift(1) 
    return g[g.x.notnull()]    

df = df.groupby('id').apply(past_window,win=10) 
print df.fillna(0) 
+0

谢谢,这似乎做到了!如果我想将70作为过去函数的一个参数(即def past(g,lookback)),那么我将如何将该参数传递给.apply(过去)? – ADJ

+0

它只是成为'apply'中的下一个参数。看到我编辑细节。 –

+0

非常感谢卡尔! – ADJ