我在计算适用于此数据集中每个单独买家的交易滚动计数时遇到问题,结构如下:
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
理想情况下,滚动交易计数窗口如下所示。 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
这里有一个类似问题的很好的答案:pandas rolling sum of last five minutes
但是,这个答案完全取决于时间戳字段,与上面不同的是,滚动计数必须在遇到来自不同用户的事务到上面行的事务时重置为 1。可以通过切片找到解决方案,但鉴于此数据集的大小(可能超过 100 万行)这是不可行的。
至关重要的是,窗口应该反射(reflect)相应行的 transactional_ts 之前的 24 小时时间段,因此我认为自定义 df.apply 或 rolling_window 方法是合适的,我只是不知道如何使它成为条件用户 ID。
最佳答案
解决方案的一部分(滚动累积和)可能已经是 here . (我只是改变了滞后的类型):
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)
该函数要求索引为日期时间类型。此外,每个 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))
groupby 选项 sort=False
可能会加快速度。 (它负责对组键进行排序。)
关于python - Pandas - 滚动窗口 - 不均匀间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37216706/