Spec-Zone.ru › Polars

polars.Expr.over

Expr.over(
    partition_by: IntoExpr | Iterable[IntoExpr] | None = None,
    *more_exprs: IntoExpr,
    order_by: IntoExpr | Iterable[IntoExpr] | None = None,
    descending: bool = False,
    nulls_last: bool = False,
    mapping_strategy: WindowMappingStrategy = 'group_to_rows',
) → Expr

Вычисляет выражения для заданных групп.

Это выражение аналогично группировке с помощью group by, агрегации и объединению результата с исходным DataFrame.

Результат аналогичен работе оконных функций в PostgreSQL.

движок:В памяти
Параметры:
partition_by

Столбец или столбцы для группировки. Принимает выражение. Строки интерпретируются как имена столбцов.

*more_exprs

Дополнительные столбцы для группировки, задаваемые позиционными аргументами.

order_by

Упорядочивает строки внутри каждой группы-раздела перед вычислением выражения. Полезно для операций, чувствительных к порядку, таких как cum_sum() или diff().

descending

Если задан параметр «order_by», указывает, выполнять сортировку по возрастанию или по убыванию.

nulls_last

Если задан параметр «order_by», указывает, размещать ли значения null в конце.

mapping_strategy: {‘group_to_rows’, ‘join’, ‘explode’}
  • group_to_rows

    Если агрегация возвращает несколько значений для каждой группы, сопоставляет их позициям строк в DataFrame. Это возможно только в том случае, если до и после агрегации для каждой группы получается одинаковое количество элементов. Если агрегация возвращает одно скалярное значение для каждой группы, это значение будет сопоставлено каждой строке.

  • join

    Если агрегация может возвращать несколько значений для каждой группы, объединяет их в ‘List<group_dtype>’ для каждой позиции строки. Предупреждение: это может потребовать много памяти. Если агрегация всегда возвращает одно скалярное значение для каждой группы, объединяет это значение как ‘<group_dtype>’ для каждой позиции строки.

  • explode

    Если агрегация может возвращать несколько значений для каждой группы, сопоставляет каждое значение новой строке, аналогично результатам group_by + agg + explode. Если агрегация всегда возвращает одно скалярное значение для каждой группы, сопоставляет это значение одной позиции строки. Если заданные группы не входят в оконную операцию, требуется их сортировка; в противном случае результат не будет иметь смысла. Эта операция изменяет количество строк.

Примеры

Передайте имя столбца, чтобы вычислить выражение для этого столбца.

>>> df = pl.DataFrame(
...     {
...         "a": ["a", "a", "b", "b", "b"],
...         "b": [1, 2, 3, 5, 3],
...         "c": [5, 4, 3, 2, 1],
...     }
... )
>>> df.with_columns(c_max=pl.col("c").max().over("a"))
shape: (5, 4)
┌─────┬─────┬─────┬───────┐
│ a   ┆ b   ┆ c   ┆ c_max │
│ --- ┆ --- ┆ --- ┆ ---   │
│ str ┆ i64 ┆ i64 ┆ i64   │
╞═════╪═════╪═════╪═══════╡
│ a   ┆ 1   ┆ 5   ┆ 5     │
│ a   ┆ 2   ┆ 4   ┆ 5     │
│ b   ┆ 3   ┆ 3   ┆ 3     │
│ b   ┆ 5   ┆ 2   ┆ 3     │
│ b   ┆ 3   ┆ 1   ┆ 3     │
└─────┴─────┴─────┴───────┘

Также поддерживается ввод выражения.

>>> df.with_columns(c_max=pl.col("c").max().over(pl.col("b") // 2))
shape: (5, 4)
┌─────┬─────┬─────┬───────┐
│ a   ┆ b   ┆ c   ┆ c_max │
│ --- ┆ --- ┆ --- ┆ ---   │
│ str ┆ i64 ┆ i64 ┆ i64   │
╞═════╪═════╪═════╪═══════╡
│ a   ┆ 1   ┆ 5   ┆ 5     │
│ a   ┆ 2   ┆ 4   ┆ 4     │
│ b   ┆ 3   ┆ 3   ┆ 4     │
│ b   ┆ 5   ┆ 2   ┆ 2     │
│ b   ┆ 3   ┆ 1   ┆ 4     │
└─────┴─────┴─────┴───────┘

Чтобы сгруппировать данные по нескольким столбцам, передайте несколько имён столбцов или выражений.

>>> df.with_columns(c_min=pl.col("c").min().over("a", pl.col("b") % 2))
shape: (5, 4)
┌─────┬─────┬─────┬───────┐
│ a   ┆ b   ┆ c   ┆ c_min │
│ --- ┆ --- ┆ --- ┆ ---   │
│ str ┆ i64 ┆ i64 ┆ i64   │
╞═════╪═════╪═════╪═══════╡
│ a   ┆ 1   ┆ 5   ┆ 5     │
│ a   ┆ 2   ┆ 4   ┆ 4     │
│ b   ┆ 3   ┆ 3   ┆ 1     │
│ b   ┆ 5   ┆ 2   ┆ 1     │
│ b   ┆ 3   ┆ 1   ┆ 1     │
└─────┴─────┴─────┴───────┘

Стратегия сопоставления join объединяет значения по группам.

>>> df.with_columns(
...     c_pairs=pl.col("c").head(2).over("a", mapping_strategy="join")
... )
shape: (5, 4)
┌─────┬─────┬─────┬───────────┐
│ a   ┆ b   ┆ c   ┆ c_pairs   │
│ --- ┆ --- ┆ --- ┆ ---       │
│ str ┆ i64 ┆ i64 ┆ list[i64] │
╞═════╪═════╪═════╪═══════════╡
│ a   ┆ 1   ┆ 5   ┆ [5, 4]    │
│ a   ┆ 2   ┆ 4   ┆ [5, 4]    │
│ b   ┆ 3   ┆ 3   ┆ [3, 2]    │
│ b   ┆ 5   ┆ 2   ┆ [3, 2]    │
│ b   ┆ 3   ┆ 1   ┆ [3, 2]    │
└─────┴─────┴─────┴───────────┘

Стратегия сопоставления explode сопоставляет значения новым строкам, изменяя структуру данных.

>>> df.select(
...     c_first_2=pl.col("c").head(2).over("a", mapping_strategy="explode")
... )
shape: (4, 1)
┌───────────┐
│ c_first_2 │
│ ---       │
│ i64       │
╞═══════════╡
│ 5         │
│ 4         │
│ 3         │
│ 2         │
└───────────┘

Вы также можете использовать выражения, не выполняемые поэлементно, с over. По умолчанию они вычисляются с учётом порядка строк, но вы можете задать другой порядок с помощью order_by.

>>> from datetime import date
>>> df = pl.DataFrame(
...     {
...         "store_id": ["a", "a", "b", "b"],
...         "date": [
...             date(2024, 9, 18),
...             date(2024, 9, 17),
...             date(2024, 9, 18),
...             date(2024, 9, 16),
...         ],
...         "sales": [7, 9, 8, 10],
...     }
... )
>>> df.with_columns(
...     cumulative_sales=pl.col("sales")
...     .cum_sum()
...     .over("store_id", order_by="date")
... )
shape: (4, 4)
┌──────────┬────────────┬───────┬──────────────────┐
│ store_id ┆ date       ┆ sales ┆ cumulative_sales │
│ ---      ┆ ---        ┆ ---   ┆ ---              │
│ str      ┆ date       ┆ i64   ┆ i64              │
╞══════════╪════════════╪═══════╪══════════════════╡
│ a        ┆ 2024-09-18 ┆ 7     ┆ 16               │
│ a        ┆ 2024-09-17 ┆ 9     ┆ 9                │
│ b        ┆ 2024-09-18 ┆ 8     ┆ 18               │
│ b        ┆ 2024-09-16 ┆ 10    ┆ 10               │
└──────────┴────────────┴───────┴──────────────────┘

Если порядок групп не требуется сохранять, более производительный вариант — использовать mapping_strategy='explode'. Однако будьте внимательны: используйте его только в инструкции select, а не в инструкции with_columns.

>>> window = {
...     "partition_by": "store_id",
...     "order_by": "date",
...     "mapping_strategy": "explode",
... }
>>> df.select(
...     pl.all().over(**window),
...     cumulative_sales=pl.col("sales").cum_sum().over(**window),
... )
shape: (4, 4)
┌──────────┬────────────┬───────┬──────────────────┐
│ store_id ┆ date       ┆ sales ┆ cumulative_sales │
│ ---      ┆ ---        ┆ ---   ┆ ---              │
│ str      ┆ date       ┆ i64   ┆ i64              │
╞══════════╪════════════╪═══════╪══════════════════╡
│ a        ┆ 2024-09-17 ┆ 9     ┆ 9                │
│ a        ┆ 2024-09-18 ┆ 7     ┆ 16               │
│ b        ┆ 2024-09-16 ┆ 10    ┆ 10               │
│ b        ┆ 2024-09-18 ┆ 8     ┆ 18               │
└──────────┴────────────┴───────┴──────────────────┘

© 2020 Ritchie Vink
© 2022 Polars contributors
Licensed under the MIT License.
https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.Expr.over.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API