Implementation:Pola rs Polars Group By Dynamic
| Knowledge Sources | |
|---|---|
| Domains | Data Engineering, Time Series |
| Last Updated | 2026-02-09 10:00 GMT |
Overview
Concrete API for grouping a sorted DataFrame into temporal windows and computing aggregations within each window, supporting tumbling windows, sliding windows, and panel data grouping.
Description
DataFrame.group_by_dynamic(index_column, every, ...) creates a DynamicGroupBy object that partitions the DataFrame into temporal windows. The .agg(*exprs) method then computes aggregate expressions within each window. The temporal index column must be sorted in ascending order before calling this method.
The method supports both simple time-based grouping (single entity) and panel data grouping (multiple entities) via the optional group_by parameter. The include_boundaries flag adds explicit window boundary columns to the output for inspection.
Usage
Use group_by_dynamic whenever you need to:
- Compute periodic aggregations (yearly, monthly, hourly summaries).
- Create overlapping window aggregations for smoothed statistics.
- Aggregate panel data across temporal windows grouped by entity.
Code Reference
Source Location
- Repository: Polars
- File:
docs/source/src/python/user-guide/transformations/time-series/rolling.py(lines 14-66)
Signature
DataFrame.group_by_dynamic(
index_column: str,
*,
every: str | timedelta,
period: str | timedelta | None = None,
offset: str | timedelta | None = None,
closed: str = "left",
label: str = "left",
group_by: str | Sequence[str] | None = None,
start_by: str = "window",
include_boundaries: bool = False,
) -> DynamicGroupBy
DynamicGroupBy.agg(
*aggs: Expr | Sequence[Expr],
**named_aggs: Expr,
) -> DataFrame
Import
import polars as pl
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| index_column | str |
Yes | Name of the sorted temporal column to window over |
| every | timedelta | Yes | Window step size as a duration string (e.g., "1y", "1mo", "1h", "30m")
|
| period | timedelta | None | No | Window duration; defaults to every (tumbling windows); set larger for sliding windows
|
| closed | str |
No | Boundary inclusion: "left" (default), "right", "both", or "none"
|
| group_by | Sequence[str] | None | No | Additional grouping columns for panel data |
| include_boundaries | bool |
No | If True, add _lower_boundary and _upper_boundary columns to output (default: False)
|
| aggs | Sequence[Expr] | Yes (for .agg()) |
Aggregation expressions to compute within each window |
Outputs
| Name | Type | Description |
|---|---|---|
| result | pl.DataFrame |
DataFrame with one row per window (and per group, if group_by is set), containing the temporal index and aggregated columns. Optionally includes _lower_boundary and _upper_boundary columns.
|
Usage Examples
Annual Average
import polars as pl
df = pl.read_csv("apple_stock.csv", try_parse_dates=True).sort("Date")
# Compute annual average closing price
annual = df.group_by_dynamic("Date", every="1y").agg(
pl.col("Close").mean()
)
print(annual)
Monthly Aggregation with Boundaries
import polars as pl
df = pl.read_csv("apple_stock.csv", try_parse_dates=True).sort("Date")
# Monthly mean close and total volume
monthly = df.group_by_dynamic(
"Date", every="1mo", period="1mo", closed="left"
).agg(
pl.col("Close").mean(),
pl.col("Volume").sum(),
)
print(monthly)
Panel Data with Additional Grouping
import polars as pl
from datetime import datetime
df = pl.DataFrame(
{
"time": [
datetime(2021, 12, 16),
datetime(2021, 12, 16),
datetime(2021, 12, 17),
datetime(2021, 12, 17),
],
"groups": ["a", "a", "a", "b"],
"values": [1, 2, 3, 4],
}
).sort("time")
result = df.group_by_dynamic(
"time", every="1h", closed="both", group_by="groups", include_boundaries=True
).agg(pl.len())
print(result)