tom*_*ler 6 python time-series pandas
我在解决此数据集中适用于每个买家的滚动交易数量时遇到问题,结构如下:
userID itemID transaction_ts
3229 4493320 2016-01-02 14:55:00
3229 4492492 2016-01-02 14:57:02
3229 4496756 2016-01-04 09:01:18
3229 4493673 2016-01-04 09:11:10
3229 4497531 2016-01-04 11:05:25
3229 4495006 2016-01-05 07:25:11
4330 4500695 2016-01-02 09:17:21
4330 4500656 2016-01-03 09:19:28
4330 4503087 2016-01-04 07:42:15
4330 4501846 2016-01-04 08:55:24
4330 4504105 2016-01-04 09:59:35
Run Code Online (Sandbox Code Playgroud)
理想情况下,对于例如24小时的滚动事务计数窗口,它看起来如下所示:
userID itemID transaction_ts rolling_count
3229 4493320 2016-01-02 14:55:00 1
3229 4492492 2016-01-02 14:57:02 2
3229 4496756 2016-01-04 09:01:18 1
3229 4493673 2016-01-04 09:11:10 2
3229 4497531 2016-01-04 11:05:25 3
3229 4495006 2016-01-05 07:25:11 4
4330 4500695 2016-01-02 09:17:21 1
4330 4500656 2016-01-03 09:19:28 1
4330 4503087 2016-01-04 07:42:15 2
4330 4501846 2016-01-04 08:55:24 3
4330 4504105 2016-01-04 09:59:35 3
Run Code Online (Sandbox Code Playgroud)
这里有类似问题的优秀答案:熊猫滚动最后五分钟的总和
但是,这个答案完全取决于时间戳字段,与上面的情况不同,滚动计数在遇到从不同用户到上一行的事务时必须重置为1.可以通过切片找到解决方案,但是给定该数据集的大小(可能是1m +行)是不可行的.
至关重要的是,窗口应该反映相应行的transactional_ts之前的24小时时段,因此为什么我认为自定义df.apply或rolling_window方法是合适的,我只是无法弄清楚如何在userID上进行条件限制.
解决方案的一部分(滚动累积和)可能已经在这里。(我只改变了滞后的类型):
from datetime import timedelta
def msum(s, lag):
lag = s.index - timedelta(days=lag)
inds = np.searchsorted(s.index.astype(np.int64), lag.astype(np.int64))
cs = s.cumsum()
return pd.Series(cs.values - cs[inds].values + s[inds].values, index=s.index)
Run Code Online (Sandbox Code Playgroud)
该函数要求索引为日期时间类型。此外,每个 userID 组内的索引应该已经排序(例如,如您的示例中所示)。
df = df.set_index('transaction_ts')
df['rolling_count'] = 1
df['rolling_count'] = df.groupby('userID', sort=False)['rolling_count'].transform(lambda x : msum(x,1))
Run Code Online (Sandbox Code Playgroud)
groupby 选项sort=False可能会提高一些速度。(它负责对组键进行排序。)