Python – скользящая индексация в библиотеке Polars?

Я хотел бы спросить, знает ли кто-нибудь, как выполнять скользящую индексацию в полярах? Я лично попробовал несколько решений, которые мне не помогли (покажу их ниже):

Что я хотел бы сделать: индексировать количество вхождений за последние X дней по имени. Пример. Допустим, я хотел бы проиндексировать события за последние 2 дня:

Имя Дата Прилавок Джон 1 янв 23 1 Джон 1 янв 23 2 Джон 1 янв 23 3 Джон 1 янв 23 4 Джон 2 янв 23 5 Джон 2 янв 23 6 Джон 2 янв 23 7 Джон 2 янв 23 8 Джон 3 янв 23 5 Джон 3 янв 23 6 Новый парень 1 янв 23 1

В этом случае счетчик сбрасывается на «1», начиная с последних X дней (например, для 3 января 23 года он начинается с «1» со 2 января 23 года) или если обнаружено новое имя.

Что я пробовал:

df.groupby_rolling(index_column='Date', period='2d', by='Name', check_sorted=False).agg((pl.col("Date").rank(method='ordinal')).alias("Counter"))

Вышеупомянутое не работает, потому что выводит:

Имя Дата Прилавок Джон 1 янв 23 1,2,3,4 Джон 1 янв 23 1,2,3,4 Джон 1 янв 23 1,2,3,4 Джон 1 янв 23 1,2,3,4 Джон 2 янв 23 1...8 Джон 2 янв 23 1...8 Джон 2 янв 23 1...8 Джон 2 янв 23 1...8 Джон 3 янв 23 1...6 Джон 3 янв 23 1...6 Новый парень 1 янв 23 1
df.with_columns( Counter=pl.col("mask").rolling_sum(window_size='2d', by = "Date") )

Где я создал столбец «Маска», который представляет собой просто столбец «1», и попытался их просуммировать, но выводит:

Имя Дата Маска Прилавок Джон 1 янв 23 1 4 Джон 1 янв 23 1 4 Джон 1 янв 23 1 4 Джон 1 янв 23 1 4 Джон 2 янв 23 1 8 Джон 2 янв 23 1 8 Джон 2 янв 23 1 8 Джон 2 янв 23 1 8 Джон 3 янв 23 1 6 Джон 3 янв 23 1 6

И он также не может правильно обработать «Нового парня», потому что Rolling_sum не может сделать по = «Имя», «Дата»

df.with_columns(Counter = pl.col("Date").rank(method='ordinal').over(["Name", "Date"]) )

Приведенный выше код работает правильно, но его можно использовать только для индексации в течение одного дня (т. е. period="1d").

Дополнительные примечания: я также сделал это в Excel, а также использовал метод грубого/необработанного цикла «for». Оба работали отлично, однако им приходилось сталкиваться с огромными объемами данных.

Что я прочитал: Некоторые ссылки для помощи в ответах: (Большинство из них не сработало, потому что у них фиксированное скользящее окно вместо динамического окна по «Дате»)

Как реализовать скользящий ранг в Polars версии 0.19

https://github.com/pola-rs/polars/issues/4808

Как сделать group_by_rolling сгруппированным по дням и часам в полярах в Python?

Как группировать и катать поляры?

https://docs.pola.rs/py-polars/html/reference/series/api/polars.Series.rank.html

https://docs.pola.rs/py-polars/html/reference/dataframe/api/polars.DataFrame.groupby_rolling.html

Можете ли вы также поделиться примером ожидаемого результата? Это облегчило бы предложение подходящего решения.

Hericks 29.04.2024 12:50

Вы хотите сказать, что начинаете только со столбцов «Имя», «Дата» и «Счетчик» — это ожидаемый результат, который вы хотите сгенерировать?

jqurious 29.04.2024 14:02

@Hericks, пример ожидаемого результата находится в разделе «Что я хотел бы сделать: индексировать количество вхождений за последние X дней по имени».

user24758287 02.05.2024 04:53

@jqurious Ага! Это верно!

user24758287 02.05.2024 04:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
115
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете начать с подхода, дающего максимальное значение для каждой группы (используя pl.len() внутри агрегирования), а затем выполнить постобработку столбца Counter, чтобы его значения увеличивались внутри каждой группы.

(
    df
    .rolling(index_column = "Date", period = "2d", group_by = "Name", check_sorted=False)
    .agg(
        pl.len().alias("Counter")
    )
    .with_columns(
        (pl.col("Counter") - pl.len() + 1 + pl.int_range(pl.len())).over("Name", "Date")
    )
)
shape: (11, 3)
┌─────────┬────────────┬─────────┐
│ Name    ┆ Date       ┆ Counter │
│ ---     ┆ ---        ┆ ---     │
│ str     ┆ date       ┆ i64     │
╞═════════╪════════════╪═════════╡
│ John    ┆ 2023-01-01 ┆ 1       │
│ John    ┆ 2023-01-01 ┆ 2       │
│ John    ┆ 2023-01-01 ┆ 3       │
│ John    ┆ 2023-01-01 ┆ 4       │
│ John    ┆ 2023-01-02 ┆ 5       │
│ John    ┆ 2023-01-02 ┆ 6       │
│ John    ┆ 2023-01-02 ┆ 7       │
│ John    ┆ 2023-01-02 ┆ 8       │
│ John    ┆ 2023-01-03 ┆ 5       │
│ John    ┆ 2023-01-03 ┆ 6       │
│ New Guy ┆ 2023-01-01 ┆ 1       │
└─────────┴────────────┴─────────┘

Объяснение. После агрегирования столбец Counter примет постоянное значение V в каждой группе имени-даты длиной L. Цель состоит в том, чтобы вместо этого заставить Counter принимать значения V-L+1 в V (по одному значению для каждой строки).

Поэтому мы можем

  1. вычтите L-1 из Counter и
  2. добавьте диапазон int с возрастающими значениями от 0 до L-1.

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