Создание столбца скользящей суммы, который сбрасывается при достижении порога - PullRequest
3 голосов
/ 02 апреля 2020

Этот вопрос не похож на другие подобные вопросы, которые я мог найти, потому что я пытаюсь объединить окно просмотра и порог в одну скользящую сумму. На самом деле я не уверен, что то, что я пытаюсь сделать, достижимо за один шаг:

У меня есть pandas фрейм данных со столбцом datetime и столбцом значения. Я создал столбец, который суммирует столбец значений (V) за скользящее временное окно. Однако я бы хотел, чтобы эта скользящая сумма сбрасывалась в 0, как только она достигает определенного порога.

Я не знаю, возможно ли это сделать за один шаг манипулирования столбцом, поскольку на каждом шаге в сумме действуют два условия - окно просмотра и порог. Если у кого-то есть идеи о том, возможно ли это и как я могу этого достичь, пожалуйста, дайте мне знать. Я знаю, как сделать это итеративно, однако это очень и очень медленно (мой фрейм данных> 1 миллиона записей).

Пример:

Время просмотра: 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        | 
+---+-----------------------+-------+---------+----------------+

В этом примере суммарная сумма не учитывает никаких значений в строке или перед строкой, которая нарушает (или равна) пороговое значение 3.

1 Ответ

0 голосов
/ 02 апреля 2020

Я не смог найти векторизованный способ сброса к 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

Это займет всего несколько секунд для массива длиной 1000000 на моей машине i5 (~ 90 с для 10 000 000)

...