Partitioned aggregates
Add a group-level statistic to every original row without manually joining an aggregate.
Polars · Module
Computes an expression over partitions while retaining a row-oriented result. It supports partition keys, optional within-partition ordering, and selectable mapping strategies for multi-value results.
.over evaluates an expression within partitions defined by one or more expressions, then maps the result back to the original rows. It can optionally order rows inside each partition and choose how multi-value results are mapped.
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| Name | Type | Description |
|---|---|---|
partition_by | IntoExpr | Iterable[IntoExpr] | None = None | Expression or expressions defining the partitions; strings are treated as column names. |
more_exprs | IntoExpr | Additional positional expressions used as partition keys. |
order_by | IntoExpr | Iterable[IntoExpr] | None = None | Expression or expressions controlling row order within each partition. |
descending | bool = False | Reverse the order_by direction when ordering is specified. |
nulls_last | bool = False | Place null values last when ordering is specified. |
mapping_strategy | WindowMappingStrategy = 'group_to_rows' | Controls how multi-value results are mapped back to rows. |
An Expr representing the partitioned expression.
.over to evaluate an expression independently within each selected partition.order_by controls the order used inside each partition before the expression runs."team" is interpreted as a column reference.join mapping strategy stores multiple values as a list on each row, which can consume substantial memory.explode only when the input is appropriately sorted, because it flattens partition results into rows.import polars as pl
df = pl.DataFrame({
"team": ["A", "A", "B"],
"score": [10, 20, 15],
})
result = df.with_columns(
pl.col("score").mean().over("team").alias("team_mean")
)
print(result)Adds each team's mean score to every row in that team.
Add a group-level statistic to every original row without manually joining an aggregate.
Calculate cumulative or difference-based expressions in a defined per-group order.
Produce list-valued or flattened multi-result outputs from partitioned expressions.
Expr.over do?over evaluates an expression separately for each partition and returns the result in the original DataFrame context. For a scalar aggregation such as mean, that value is mapped to every row in its partition.
Follow-up: How would you make a cumulative calculation within each group? Use order_by with an order-sensitive expression such as cum_sum() or diff().
partition_by identifies the groups, and additional positional expressions can supply more grouping keys. Strings are interpreted as column names, while expressions are evaluated as Polars expressions.
Follow-up: How can rows be ordered before evaluation? Pass an expression or iterable to order_by, then set descending or nulls_last as needed.
group_to_rows maps results back to their original row positions and requires compatible group and result lengths for multi-value results. join attaches values as lists, while explode flattens values into new rows.
Follow-up: Which strategy is generally safest for a scalar aggregation? group_to_rows, because one scalar can be mapped to every row without creating list-valued columns or changing row shape.
polars.Expr.groupbypolars.Expr.cum_sumpolars.Expr.diffpolars.Expr.sort