> ## Documentation Index
> Fetch the complete documentation index at: https://nixtla-mintlify-2a3f5c2a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Built-in lag transformations

# Lag transforms

##

The `mlforecast.lag_transforms` module provides built-in **lag
transformations**: statistics computed over lagged values of the target that
are used as features by the forecasting model. You pass them to `MLForecast`
through the `lag_transforms` argument, a dict whose keys are the lags to apply
the transformation to and whose values are lists of transformation instances.

```python theme={null}
from mlforecast import MLForecast
from mlforecast.lag_transforms import ExpandingStd, RollingMean

fcst = MLForecast(
    models=[...],
    freq='D',
    lag_transforms={
        1: [ExpandingStd()],
        7: [RollingMean(window_size=7), RollingMean(window_size=28)],
    },
)
```

The transforms fall into four families, each with several variants:

* **Rolling** — `RollingMean`, `RollingStd`, `RollingMin`, `RollingMax`,
  `RollingQuantile`: fixed-window statistics over the lagged target.
* **Seasonal rolling** — `SeasonalRollingMean`, `SeasonalRollingStd`,
  `SeasonalRollingMin`, `SeasonalRollingMax`, `SeasonalRollingQuantile`:
  rolling statistics computed across same-position observations in successive
  seasons (e.g. last 4 Mondays).
* **Expanding** — `ExpandingMean`, `ExpandingStd`, `ExpandingMin`,
  `ExpandingMax`, `ExpandingQuantile`: statistics over all observations up to
  the lag.
* **Exponentially weighted** — `ExponentiallyWeightedMean`: a weighted mean
  that emphasises recent observations.

Two combinators let you build richer features from these primitives:
**`Offset`** applies a transformation at a shifted lag, and **`Combine`**
joins two transformations with a binary operator (for example a ratio of two
rolling means at different windows).

The basic usage is per-series — each transformation is computed independently
for every series. The next section describes how to instead compute these
statistics **across multiple series at once**.

For a worked walkthrough of all of the above, including the `Combine` /
`Offset` combinators and how to plug in custom numba-based transforms, see
the [Lag transformations](docs/how-to-guides/lag_transforms_guide.html)
how-to guide.

## Pooled mode: `global_`, `groupby`, and `partition_by`

Every built-in rolling, expanding, seasonal-rolling, and exponentially weighted
transform accepts three pooling parameters that let you compute the statistic
across **multiple series at once**:

* **`global_: bool`** — when `True`, the statistic is computed across **all
  series** aggregated by timestamp. Every series receives the same feature
  value at each timestamp.
* **`groupby: Sequence[str]`** — column names to group by before computing the
  statistic. Columns must be declared as static features when calling
  `fit` / `preprocess`. Series in the same group share the feature value at
  each timestamp; series in different groups get different values.
* **`partition_by: Sequence[str]`** — column names to partition further along
  a **dynamic** (time-varying) key, such as `promo` or `regime`. Each unique
  combination of partition values gets its own bucket. Composes with `global_`
  (cross-series aggregates within each partition), with `groupby` (group
  aggregates within each partition), or stands alone (per-(id, partition)
  buckets — *local* mode). Partition columns must be supplied via `X_df` at
  prediction.

`global_` and `groupby` are **mutually exclusive** on the same transform.
`partition_by` composes with either one or stands alone. All pooled modes
require every series to **end at the same timestamp**, including local
`partition_by`.

**RANGE semantics.** Pooled transforms use SQL-style
`RANGE BETWEEN ... PRECEDING` windows over actual timestamps, not row
positions. Series with staggered starts simply do not contribute to the window
until they have observations — no synthetic zeros are injected. Pooled mode
assumes a **continuous, gap-free time grid** within each series; combining
`validate_data=False` with a pooled transform raises a `UserWarning`. For
`partition_by`, ordinals come from the **parent calendar** (global or group
scope for nonlocal modes, per-id for local mode), so a partition bucket with
gaps still preserves RANGE window semantics across those gaps rather than
collapsing to row-based behavior.

**`min_samples` divergence.** In local (per-series) mode, `min_samples` is
capped at `window_size` by `coreforecast`. In pooled mode, `min_samples`
counts **total non-NaN observations across all series** in the bucket within
the rolling window, with no capping. This makes it useful as a coverage
threshold: `RollingMean(window_size=1, min_samples=2, groupby=["brand"])`
produces a non-null value only at timestamps where at least two series in the
brand contribute observations.

See the [Pooled lag transforms](docs/how-to-guides/pooled_lag_transforms.html)
how-to guide for end-to-end examples.

### `RollingQuantile`

```python theme={null}
RollingQuantile(p, window_size, min_samples=None, global_=False, groupby=None, partition_by=None, time_agg=None, **kwargs)
```

Bases: <code>[\_RollingBase](#mlforecast.lag_transforms._RollingBase)</code>

Rolling quantile.

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) this
  transform has no aggregate-cache fast path: it falls back to a
  row-level pass whose cost grows with `unique timestamps x bucket
    rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `RollingMax`

Bases: <code>[\_RollingBase](#mlforecast.lag_transforms._RollingBase)</code>

Rolling statistic

### `RollingMin`

Bases: <code>[\_RollingBase](#mlforecast.lag_transforms._RollingBase)</code>

Rolling statistic

### `RollingStd`

Bases: <code>[\_RollingBase](#mlforecast.lag_transforms._RollingBase)</code>

Rolling statistic

### `RollingMean`

Bases: <code>[\_RollingBase](#mlforecast.lag_transforms._RollingBase)</code>

Rolling statistic

### `SeasonalRollingQuantile`

```python theme={null}
SeasonalRollingQuantile(p, season_length, window_size, min_samples=None, global_=False, groupby=None, partition_by=None, time_agg=None, **kwargs)
```

Bases: <code>[\_Seasonal\_RollingBase](#mlforecast.lag_transforms._Seasonal_RollingBase)</code>

Rolling statistic over seasonal periods

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) seasonal
  rolling transforms have no aggregate-cache fast path: they fall back
  to a row-level pass whose cost grows with `unique timestamps x
    bucket rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `SeasonalRollingMax`

Bases: <code>[\_Seasonal\_RollingBase](#mlforecast.lag_transforms._Seasonal_RollingBase)</code>

Rolling statistic over seasonal periods

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) seasonal
  rolling transforms have no aggregate-cache fast path: they fall back
  to a row-level pass whose cost grows with `unique timestamps x
    bucket rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `SeasonalRollingMin`

Bases: <code>[\_Seasonal\_RollingBase](#mlforecast.lag_transforms._Seasonal_RollingBase)</code>

Rolling statistic over seasonal periods

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) seasonal
  rolling transforms have no aggregate-cache fast path: they fall back
  to a row-level pass whose cost grows with `unique timestamps x
    bucket rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `SeasonalRollingStd`

Bases: <code>[\_Seasonal\_RollingBase](#mlforecast.lag_transforms._Seasonal_RollingBase)</code>

Rolling statistic over seasonal periods

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) seasonal
  rolling transforms have no aggregate-cache fast path: they fall back
  to a row-level pass whose cost grows with `unique timestamps x
    bucket rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `SeasonalRollingMean`

Bases: <code>[\_Seasonal\_RollingBase](#mlforecast.lag_transforms._Seasonal_RollingBase)</code>

Rolling statistic over seasonal periods

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) seasonal
  rolling transforms have no aggregate-cache fast path: they fall back
  to a row-level pass whose cost grows with `unique timestamps x
    bucket rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `ExpandingQuantile`

```python theme={null}
ExpandingQuantile(p, global_=False, groupby=None, partition_by=None, time_agg=None, **kwargs)
```

Bases: <code>[\_ExpandingBase](#mlforecast.lag_transforms._ExpandingBase)</code>

Expanding quantile.

<details class="note" open markdown="1">
  <summary>Note</summary>

  In pooled modes (`global_`/`groupby`/`partition_by`) this
  transform has no aggregate-cache fast path: it falls back to a
  row-level pass whose cost grows with `unique timestamps x bucket
    rows` at fit, and aggregates are rebuilt at every recursive
  prediction step. Can be slow on large panels.
</details>

### `ExpandingMax`

Bases: <code>[\_ExpandingBase](#mlforecast.lag_transforms._ExpandingBase)</code>

Expanding statistic

**Parameters:**

| Name           | Type                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default    |
| -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `global_`      | <code>bool</code>           | If True, compute the statistic across all series aggregated by timestamp. Requires all series to end at the same timestamp. Defaults to False.                                                                                                                                                                                                                                                                                                                          | *required* |
| `groupby`      | <code>Sequence\[str]</code> | Column names to group by before computing the statistic. Columns must be static features. Mutually exclusive with `global_`. Defaults to None.                                                                                                                                                                                                                                                                                                                          | *required* |
| `partition_by` | <code>Sequence\[str]</code> | Column names to partition by. Each unique combination of partition values creates a separate bucket. Unlike `groupby`, partition columns may vary over time and must be supplied via `X_df` at prediction. Composes with `global_` (cross-series aggregates within each partition), `groupby` (group aggregates within each partition), or stands alone (per-(id, partition) buckets, *local* mode). See the Pooled lag transforms guide for details. Defaults to None. | *required* |
| `time_agg`     | <code>str</code>            | Pre-aggregate all rows sharing a timestamp within each bucket into a single value before applying the transform. One of `"sum"`, `"count"`, `"mean"`, `"min"`, `"max"`. Requires `global_` or `groupby`. Defaults to None.                                                                                                                                                                                                                                              | *required* |

### `ExpandingMin`

Bases: <code>[\_ExpandingBase](#mlforecast.lag_transforms._ExpandingBase)</code>

Expanding statistic

**Parameters:**

| Name           | Type                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default    |
| -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `global_`      | <code>bool</code>           | If True, compute the statistic across all series aggregated by timestamp. Requires all series to end at the same timestamp. Defaults to False.                                                                                                                                                                                                                                                                                                                          | *required* |
| `groupby`      | <code>Sequence\[str]</code> | Column names to group by before computing the statistic. Columns must be static features. Mutually exclusive with `global_`. Defaults to None.                                                                                                                                                                                                                                                                                                                          | *required* |
| `partition_by` | <code>Sequence\[str]</code> | Column names to partition by. Each unique combination of partition values creates a separate bucket. Unlike `groupby`, partition columns may vary over time and must be supplied via `X_df` at prediction. Composes with `global_` (cross-series aggregates within each partition), `groupby` (group aggregates within each partition), or stands alone (per-(id, partition) buckets, *local* mode). See the Pooled lag transforms guide for details. Defaults to None. | *required* |
| `time_agg`     | <code>str</code>            | Pre-aggregate all rows sharing a timestamp within each bucket into a single value before applying the transform. One of `"sum"`, `"count"`, `"mean"`, `"min"`, `"max"`. Requires `global_` or `groupby`. Defaults to None.                                                                                                                                                                                                                                              | *required* |

### `ExpandingStd`

Bases: <code>[\_ExpandingBase](#mlforecast.lag_transforms._ExpandingBase)</code>

Expanding statistic

**Parameters:**

| Name           | Type                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default    |
| -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `global_`      | <code>bool</code>           | If True, compute the statistic across all series aggregated by timestamp. Requires all series to end at the same timestamp. Defaults to False.                                                                                                                                                                                                                                                                                                                          | *required* |
| `groupby`      | <code>Sequence\[str]</code> | Column names to group by before computing the statistic. Columns must be static features. Mutually exclusive with `global_`. Defaults to None.                                                                                                                                                                                                                                                                                                                          | *required* |
| `partition_by` | <code>Sequence\[str]</code> | Column names to partition by. Each unique combination of partition values creates a separate bucket. Unlike `groupby`, partition columns may vary over time and must be supplied via `X_df` at prediction. Composes with `global_` (cross-series aggregates within each partition), `groupby` (group aggregates within each partition), or stands alone (per-(id, partition) buckets, *local* mode). See the Pooled lag transforms guide for details. Defaults to None. | *required* |
| `time_agg`     | <code>str</code>            | Pre-aggregate all rows sharing a timestamp within each bucket into a single value before applying the transform. One of `"sum"`, `"count"`, `"mean"`, `"min"`, `"max"`. Requires `global_` or `groupby`. Defaults to None.                                                                                                                                                                                                                                              | *required* |

### `ExpandingMean`

Bases: <code>[\_ExpandingBase](#mlforecast.lag_transforms._ExpandingBase)</code>

Expanding statistic

**Parameters:**

| Name           | Type                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default    |
| -------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `global_`      | <code>bool</code>           | If True, compute the statistic across all series aggregated by timestamp. Requires all series to end at the same timestamp. Defaults to False.                                                                                                                                                                                                                                                                                                                          | *required* |
| `groupby`      | <code>Sequence\[str]</code> | Column names to group by before computing the statistic. Columns must be static features. Mutually exclusive with `global_`. Defaults to None.                                                                                                                                                                                                                                                                                                                          | *required* |
| `partition_by` | <code>Sequence\[str]</code> | Column names to partition by. Each unique combination of partition values creates a separate bucket. Unlike `groupby`, partition columns may vary over time and must be supplied via `X_df` at prediction. Composes with `global_` (cross-series aggregates within each partition), `groupby` (group aggregates within each partition), or stands alone (per-(id, partition) buckets, *local* mode). See the Pooled lag transforms guide for details. Defaults to None. | *required* |
| `time_agg`     | <code>str</code>            | Pre-aggregate all rows sharing a timestamp within each bucket into a single value before applying the transform. One of `"sum"`, `"count"`, `"mean"`, `"min"`, `"max"`. Requires `global_` or `groupby`. Defaults to None.                                                                                                                                                                                                                                              | *required* |

### `ExponentiallyWeightedMean`

```python theme={null}
ExponentiallyWeightedMean(alpha, global_=False, groupby=None, partition_by=None, time_agg='mean', **kwargs)
```

Bases: <code>[\_BaseLagTransform](#mlforecast.lag_transforms._BaseLagTransform)</code>

Exponentially weighted average

**Parameters:**

| Name           | Type                                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Default             |
| -------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `alpha`        | <code>[float](#float)</code>                            | Smoothing factor.                                                                                                                                                                                                                                                                                                                                                                                                                                                       | *required*          |
| `global_`      | <code>[bool](#bool)</code>                              | If True, compute the statistic across all series aggregated by timestamp. Requires all series to end at the same timestamp. Defaults to False.                                                                                                                                                                                                                                                                                                                          | <code>False</code>  |
| `groupby`      | <code>[Sequence](#typing.Sequence)\[[str](#str)]</code> | Column names to group by before computing the statistic. Columns must be static features. Mutually exclusive with `global_`. Defaults to None.                                                                                                                                                                                                                                                                                                                          | <code>None</code>   |
| `partition_by` | <code>[Sequence](#typing.Sequence)\[[str](#str)]</code> | Column names to partition by. Each unique combination of partition values creates a separate bucket. Unlike `groupby`, partition columns may vary over time and must be supplied via `X_df` at prediction. Composes with `global_` (cross-series aggregates within each partition), `groupby` (group aggregates within each partition), or stands alone (per-(id, partition) buckets, *local* mode). See the Pooled lag transforms guide for details. Defaults to None. | <code>None</code>   |
| `time_agg`     | <code>[str](#str)</code>                                | Pre-aggregate all rows sharing a timestamp within each bucket into a single value before applying the transform. One of `"sum"`, `"count"`, `"mean"`, `"min"`, `"max"`. Values other than `"mean"` require `global_` or `groupby`. Defaults to `"mean"`, which matches EWM's bucket-mean update rule: each timestamp contributes its bucket aggregate mean exactly once, regardless of how many rows aggregated there. `None` is not accepted.                          | <code>'mean'</code> |

### `Offset`

```python theme={null}
Offset(tfm, n)
```

Bases: <code>[\_BaseLagTransform](#mlforecast.lag_transforms._BaseLagTransform)</code>

Shift series before computing transformation

**Parameters:**

| Name  | Type                                       | Description                                                                  | Default    |
| ----- | ------------------------------------------ | ---------------------------------------------------------------------------- | ---------- |
| `tfm` | <code>[LagTransform](#LagTransform)</code> | Transformation to be applied                                                 | *required* |
| `n`   | <code>[int](#int)</code>                   | Number of positions to shift (lag) series before applying the transformation | *required* |

### `Combine`

```python theme={null}
Combine(tfm1, tfm2, operator)
```

Bases: <code>[\_BaseLagTransform](#mlforecast.lag_transforms._BaseLagTransform)</code>

Combine two lag transformations using an operator

**Parameters:**

| Name       | Type                                       | Description                                                          | Default    |
| ---------- | ------------------------------------------ | -------------------------------------------------------------------- | ---------- |
| `tfm1`     | <code>[LagTransform](#LagTransform)</code> | First transformation.                                                | *required* |
| `tfm2`     | <code>[LagTransform](#LagTransform)</code> | Second transformation.                                               | *required* |
| `operator` | <code>[callable](#callable)</code>         | Binary operator that defines how to combine the two transformations. | *required* |
