Вложенные операции группировки/подгруппы по времени без map_groups()?Python

Программы на Python
Ответить
Anonymous
 Вложенные операции группировки/подгруппы по времени без map_groups()?

Сообщение Anonymous »

Я хочу понять, как polars создавать временные подгруппы из групп с помощью операции прокрутки().
Я хочу сделать это, сохраняя параллель, т. е. без использования map_groups() (см. этот подход) и без использования вторичных или объединяющих фреймов данных.

Пример ввода:

Код: Выделить всё

┌─────┬─────────────────────┬───────┐
│ row ┆ date                ┆ price │
│ --- ┆ ---                 ┆ ---   │
│ i64 ┆ datetime[μs]        ┆ i64   │
╞═════╪═════════════════════╪═══════╡
│ 1   ┆ 2022-01-01 10:00:00 ┆ 10    │
│ 2   ┆ 2022-01-01 10:05:00 ┆ 20    │
│ 3   ┆ 2022-01-01 10:10:00 ┆ 30    │
│ 4   ┆ 2022-01-01 10:15:00 ┆ 40    │
│ 5   ┆ 2022-01-01 10:20:00 ┆ 50    │
│ 6   ┆ 2022-01-01 10:25:00 ┆ 60    │
│ 7   ┆ 2022-01-01 10:30:00 ┆ 70    │
│ 8   ┆ 2022-01-01 10:35:00 ┆ 80    │
│ 8   ┆ 2022-01-01 10:40:00 ┆ 90    │
│ 9   ┆ 2022-01-01 10:45:00 ┆ 100   │
│ 10  ┆ 2022-01-01 10:50:00 ┆ 110   │
│ 11  ┆ 2022-01-01 10:55:00 ┆ 120   │
│ 12  ┆ 2022-01-01 11:00:00 ┆ 130   │
└─────┴─────────────────────┴───────┘

Желаемый результат:

Код: Выделить всё

┌─────┬─────────────────────┬───────┬──────────────────────────────────┐
│ row ┆ date                ┆ price ┆ 10_min_groups_mean_price_history │
│ --- ┆ ---                 ┆ ---   ┆ ---                              │
│ i64 ┆ datetime[μs]        ┆ i64   ┆ list[i64]                        │
╞═════╪═════════════════════╪═══════╪══════════════════════════════════╡
│ 1   ┆ 2022-01-01 10:00:00 ┆ 10    ┆ [10]                             │
│ 2   ┆ 2022-01-01 10:05:00 ┆ 20    ┆ [15]                             │
│ 3   ┆ 2022-01-01 10:10:00 ┆ 30    ┆ [25, 10]                         │
│ 4   ┆ 2022-01-01 10:15:00 ┆ 40    ┆ [35, 15]                         │
│ 5   ┆ 2022-01-01 10:20:00 ┆ 50    ┆ [45, 25, 10]                     │
│ 6   ┆ 2022-01-01 10:25:00 ┆ 60    ┆ [55, 35, 15]                     │
│ 7   ┆ 2022-01-01 10:30:00 ┆ 70    ┆ [65, 45, 25]                     │
│ 8   ┆ 2022-01-01 10:35:00 ┆ 80    ┆ [75, 55, 35]                     │
│ 8   ┆ 2022-01-01 10:40:00 ┆ 90    ┆ [85, 65, 45]                     │
│ 9   ┆ 2022-01-01 10:45:00 ┆ 100   ┆ [95, 75, 55]                     │
│ 10  ┆ 2022-01-01 10:50:00 ┆ 110   ┆ [105, 85, 65]                    │
│ 11  ┆ 2022-01-01 10:55:00 ┆ 120   ┆ [115, 95, 75]                    │
│ 12  ┆ 2022-01-01 11:00:00 ┆ 130   ┆ [125, 105, 85]                   │
└─────┴─────────────────────┴───────┴──────────────────────────────────┘

Что происходит выше?

  • Прокручивающееся окно применяется к кадру данных, создавая окно на строку.
  • Каждое окно включает все строки за последние 30 минут (включая текущую строку).
  • Затем каждое 30-минутное окно делится на 10-минутные подгруппы.
  • Средняя цена рассчитывается для каждая 10-минутная подгруппа
  • Все средние цены из подгрупп возвращаются в виде списка (самые последние сначала) в столбец «10_min_groups_mean_price_history»

Работа на примере (в качестве примера используется строка 5):

  • Прокручивающееся окно для строки 5 фиксирует данные за предыдущие 30 минут, которые строки с 1 по 5
  • Эти строки подгруппированы в 10-минутные окна, образующие три подгруппы, которые охватывают строки [[5,4],[3,2],[1]]
  • Средняя цена строк в каждой подгруппе рассчитывается и отображается в виде списка → [45, 25, 10]

Ментальная модель:

Я рассматриваю это как обработку каждого окна из операции прокрутки() как кадра данных, который можно вычислить по мере необходимости (в данном случае путем выполнения над ним операции group_by_dynamic() с намерением вернуть агрегаты по этим подгруппам в виде списка), но не уверен, что это правильный способ думать об этом???
Если бы данные подгруппы были категорично, это был бы простой случай использования over(), однако я не знаю эквивалента, когда требуется подгруппировать по временным рядам?
У меня также сложилось впечатление, что эта операция должна быть распараллеливаемой, поскольку каждое окно независимо друг от друга (это просто дополнительные шаги расчета), но, пожалуйста, укажите, если есть причина, по которой это невозможно.
Заранее спасибо!

Полный набор фиктивных данных:

Если вы хотите запустить это с набором данных реалистичного размера, вы можете использовать

Код: Выделить всё

import polars as pl
from datetime import datetime, timedelta

df_dummy = pl.DataFrame({
'date' :  pl.datetime_range(
datetime(2000, 1, 1, 9),
datetime(2000, 1, 1, 16, 59, 59),
timedelta(seconds=1),
eager=True
)
})
df_dummy = df_dummy.with_columns(
pl.Series(np.random.uniform(.5,.95,len(df_dummy)) * 100 ).alias('price')
)
Другие способы задать этот вопрос (для тех, кто ищет):
  • Код: Выделить всё

    group_by_dynamic()
    внутри Rolling()
  • Как получить доступ к полярным объектам RollingGroupBy[Dataframe]
  • Обрабатывать каждое окно Rolling() как фрейм данных для агрегирования
  • Вложенные фреймы данных в контексте группировки
  • Вложенные контексты группировки


Подробнее здесь: https://stackoverflow.com/questions/752 ... map-groups
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»