首页 > 解决方案 > 创建一个滚动总和列,一旦达到阈值就会重置

问题描述

这个问题与我能找到的其他类似问题不同,因为我试图将回溯窗口和阈值组合成一个滚动总和。我实际上不确定我想要做的事情是否可以一步完成:

我有一个带有日期时间列和值列的熊猫数据框。我创建了一个列,该列在滚动时间窗口内对值列 (V) 求和。但是,一旦达到某个阈值,我希望此滚动总和重置为 0。

我不知道是否可以在一个列操作步骤中执行此操作,因为求和的每个步骤都有两个条件在起作用 - 回溯窗口和阈值。如果有人对这是否可能以及我如何实现它有任何想法,请告诉我。我知道如何迭代地执行此操作,但是它非常非常慢(我的数据框有超过 100 万个条目)。

例子:

回溯时间:3分钟

门槛:3

+---+-----------------------+-------+--------------------------+
|   |           myDate      |   V   | rolling | desired_column |
+---+-----------------------+-------+---------+----------------+
| 1 | 2020-04-01 10:00:00   | 0     |  0      |       0        |   
| 2 | 2020-04-01 10:01:00   | 1     |  1      |       1        | 
| 3 | 2020-04-01 10:02:00   | 2     |  3      |       3        | 
| 4 | 2020-04-01 10:03:00   | 1     |  4      |       1        | 
| 5 | 2020-04-01 10:04:00   | 0     |  4      |       1        | 
| 6 | 2020-04-01 10:05:00   | 4     |  7      |       5        | 
| 7 | 2020-04-01 10:06:00   | 1     |  6      |       1        | 
| 8 | 2020-04-01 10:07:00   | 1     |  6      |       2        | 
| 9 | 2020-04-01 10:08:00   | 0     |  6      |       0        |       
| 10| 2020-04-01 10:09:00   | 3     |  5      |       5        | 
+---+-----------------------+-------+---------+----------------+

在此示例中,sum rulling sum 将不考虑任何违反(或等于)阈值 3 的行上或之前的任何值。

标签: pythonpandasrolling-computation

解决方案


每次达到阈值时,我都找不到矢量化方法来重置为 0。

但是 Pandas 列的底层容器是一个 numpy 数组,迭代一个 numpy 数组需要一个可接受的时间。所以我会:

arr = np.zeros(len(df), dtype='int')
cum = 0
src = df['V'].values
dt = df['myDate'].values
start = 0
for i in range(len(df)):
    cum += src[i]
    while dt[start] < dt[i] - np.timedelta64(4, 'm'):
        cum -= src[start]
        start +=1
    arr[i] = cum
    if cum >=3:
        cum = 0
        start = i

df['desired_column'] = arr

它给 :

                myDate  V  rolling  desired_column
1  2020-04-01 10:00:00  0        0               0
2  2020-04-01 10:01:00  1        1               1
3  2020-04-01 10:02:00  2        3               3
4  2020-04-01 10:03:00  1        4               1
5  2020-04-01 10:04:00  0        4               1
6  2020-04-01 10:05:00  4        7               5
7  2020-04-01 10:06:00  1        6               1
8  2020-04-01 10:07:00  1        6               2
9  2020-04-01 10:08:00  0        6               2
10 2020-04-01 10:09:00  3        5               5

在我的 i5 机器上长度为 1000000 的数组只需要几秒钟(对于 10 000 000 大约 90 秒)


推荐阅读