Частота суммирования на основе временного интервала - PullRequest
1 голос
/ 04 июля 2019

У меня есть фрейм данных, который содержит метки времени и столбцы счетчиков.Временные метки разбросаны с интервалом в 1 минуту.Счетчик показывает количество событий, происходящих в метке времени.На каждой отметке времени я хочу рассчитать количество событий в следующие десять минут .Таким образом, при отметке времени 2018-01-03 00:00:00 число событий будет равно 3.

Я создал функцию, которой я передаю каждую строку кадра данных, и она повторно запускает число событий вследующие 10 минутЯ получаю правильный ответ, но время выполнения очень велико, и я хотел бы сделать это быстрее, потому что я намерен запустить его на большом наборе данных.Я думаю, что это может быть достигнуто быстро с эффективным использованием группового и преобразования, но я не уверен, как это сделать.Любая помощь будет оценена.Спасибо!

a = pd.DataFrame()
a['timestamp'] = pd.date_range('2018-01-03 00:00:00', '2018-01-03 00:20:00', freq='01min').to_list()
a['counter'] = 0
a['counter'][5] = 2
a['counter'][7]= 1
a['counter'][16] = 3

Фрейм данных выглядит следующим образом:

           timestamp    counter
0   2018-01-03 00:00:00 0
1   2018-01-03 00:01:00 0
2   2018-01-03 00:02:00 0
3   2018-01-03 00:03:00 0
4   2018-01-03 00:04:00 0
5   2018-01-03 00:05:00 2
6   2018-01-03 00:06:00 0
7   2018-01-03 00:07:00 1
8   2018-01-03 00:08:00 0
9   2018-01-03 00:09:00 0
10  2018-01-03 00:10:00 0
11  2018-01-03 00:11:00 0
12  2018-01-03 00:12:00 0
13  2018-01-03 00:13:00 0
14  2018-01-03 00:14:00 0
15  2018-01-03 00:15:00 0
16  2018-01-03 00:16:00 3
17  2018-01-03 00:17:00 0
18  2018-01-03 00:18:00 0
19  2018-01-03 00:19:00 0
20  2018-01-03 00:20:00 0

Я применяю следующую функцию к каждой строке df, которая вычисляет количество событий в следующие 10 минут

def count_events(a, time_diff):
    temp_df = a[(a['timestamp'] > time_diff)& (a['timestamp'] <=(time_diff + pd.Timedelta(minutes=10)))]
    events = sum(temp_df['counter'])
    return events


for i in range(len(a)):
    a['no_of_events'][i] = count_events(a, a['timestamp'][i])

Вывод (это правильный вывод):

      timestamp     counter no_of_events
0   2018-01-03 00:00:00 0   3
1   2018-01-03 00:01:00 0   3
2   2018-01-03 00:02:00 0   3
3   2018-01-03 00:03:00 0   3
4   2018-01-03 00:04:00 0   3
5   2018-01-03 00:05:00 2   1
6   2018-01-03 00:06:00 0   4
7   2018-01-03 00:07:00 1   3
8   2018-01-03 00:08:00 0   3
9   2018-01-03 00:09:00 0   3
10  2018-01-03 00:10:00 0   3
11  2018-01-03 00:11:00 0   3
12  2018-01-03 00:12:00 0   3
13  2018-01-03 00:13:00 0   3
14  2018-01-03 00:14:00 0   3
15  2018-01-03 00:15:00 0   3
16  2018-01-03 00:16:00 3   0
17  2018-01-03 00:17:00 0   0
18  2018-01-03 00:18:00 0   0
19  2018-01-03 00:19:00 0   0
20  2018-01-03 00:20:00 0   0

1 Ответ

0 голосов
/ 05 июля 2019

Как и предлагали люди в комментариях, roll - лучший способ сделать это.Кажется, что вы хотите переместиться вперед, начиная со строки, но rolling сделайте перекат назад.Вы можете решить эту проблему путем инвертирования строк вашего информационного кадра с помощью .iloc[::-1] и использовать его снова после операции прокрутки, чтобы вернуть их в правильном порядке.

b = a.iloc[::-1].rolling(10, on='timestamp', min_periods=1).sum().iloc[::-1]

b:

             timestamp  counter
0  2018-01-03 00:00:00      3.0
1  2018-01-03 00:01:00      3.0
2  2018-01-03 00:02:00      3.0
3  2018-01-03 00:03:00      3.0
4  2018-01-03 00:04:00      3.0
5  2018-01-03 00:05:00      3.0
6  2018-01-03 00:06:00      1.0
7  2018-01-03 00:07:00      4.0
8  2018-01-03 00:08:00      3.0
9  2018-01-03 00:09:00      3.0
10 2018-01-03 00:10:00      3.0
11 2018-01-03 00:11:00      3.0
12 2018-01-03 00:12:00      3.0
13 2018-01-03 00:13:00      3.0
14 2018-01-03 00:14:00      3.0
15 2018-01-03 00:15:00      3.0
16 2018-01-03 00:16:00      3.0
17 2018-01-03 00:17:00      0.0
18 2018-01-03 00:18:00      0.0
19 2018-01-03 00:19:00      0.0
20 2018-01-03 00:20:00      0.0

EDIT

Чтобы исключить текущую временную метку, вы можете использовать shift , чтобы сместить столбец счетчика на 1 позицию.Просто сделайте:

a['counter'] = a['counter'].shift(-1)

перед использованием rolling.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...