Временные ряды pandas: группировка и скользящее среднее нерегулярно расположенных данных по обычным 10-минутным окнам

У меня есть фрейм данных, который выглядит так:

|-----------------------------------------------------|
|                        | category   | pct_formation |
|-----------------------------------------------------|
|ts_timestamp            |            |               |
|-----------------------------------------------------|
|2018-10-22 10:13:44.043 | in_petr    | 37.07         |
|2018-10-22 10:17:09.527 | in_petr    | 36.97         |
|2018-10-22 10:17:43.977 | in_dsh     | 36.95         |
|2018-10-22 10:17:43.963 | in_dsh     | 36.96         |
|2018-10-22 10:17:09.527 | in_petr    | 32.96         |
|2018-10-22 10:19:44.040 | out_petr   | 36.89         |
|2018-10-23 10:19:44.043 | out_petr   | 36.90         |
|2018-10-23 10:19:37.267 | sync       | 33.91         |
|2018-10-23 10:19:44.057 | sync       | 36.96         |
|2018-10-23 10:19:16.750 | out_petr   | 36.88         |
|2018-10-23 10:20:03.160 | sync       | 36.98         |
|2018-10-23 10:20:32.350 | sync       | 37.00         |
|2018-10-23 10:23:03.150 | sync       | 34.58         |
|2018-10-23 10:22:18.633 | in_dsh     | 36.98         |
|2018-10-23 10:25:39.557 | in_dsh     | 36.97         |
|-----------------------------------------------------|

Данные содержат значения pct_formation для различных категорий, собранные в разное время каждый день (нерегулярная частота, неравномерное расстояние).

Я хочу сравнить средний pct_formation каждой категории для 10-минутного скользящего окна между 9:00 и 11:00 каждый день или в среднем за неделю.

Проблема в том, что данные по каждой категории не всегда начинают поступать в 9 утра. У некоторых он начинается в 9:10, у кого-то в 9.15, у кого-то в 10 утра и так далее. Кроме того, данные не поступают через регулярные промежутки времени. Как я могу получить 10-минутное скользящее среднее для каждого дня и каждой категории с 9:00 до 11:00?

Изначально я преобразовал столбец ts_timestamp в индекс:

df = df.set_index('ts_timestamp')

Затем я могу groupby и использовать rolling() как таковой:

df.groupby('category').rolling('10T').agg({'pct_formation': 'mean'})

Однако это не показывает мне регулярные 10-минутные интервалы, а показывает временные метки из фрейма данных.

Я понимаю, что мне нужно создать диапазон данных, который будет использоваться в качестве индекса:

pd.date_range(start=df.index.min().replace(hour=9, minute=0, second=0, microsecond=0),
              end=df.index.max().replace(hour=11, minute=0, second=0, microsecond=0),
              freq='10T')
#
# or should I use freq='1T' so that rolling() can do 10 minute intervals?

Но как я могу выровнять мой фрейм данных с этим диапазоном? Как я могу усреднить несколько значений, которые встречаются в диапазоне?

Я новичок в работе с данными временных рядов и буду признателен за любую помощь. Пожалуйста, не стесняйтесь спрашивать, если что-то непонятно.

Катание с учетом времени - это то, что вы ищете: stackoverflow.com/a/41176540

toliveira 08.10.2020 00:23
1
1
619
1

Ответы 1

Использование pd.Grouper:

df.groupby(['category', pd.Grouper(key = 'ts_timestamp', freq = '10Min')]).\ agg({'pct_formation': 'mean'})

Выход:

                                    pct
cat      ts                            
in_dsh   2018-10-22 10:10:00  36.955000
in_petr  2018-10-22 10:10:00  35.666667
out_petr 2018-10-22 10:10:00  36.890000
         2018-10-23 10:10:00  36.900000
sync     2018-10-23 10:10:00  35.435000

Другие вопросы по теме