Transforms¶
Composable transforms with a fit / apply lifecycle.
See the transforms guide for how to write your own.
transforms
¶
Composable series transforms with a fit / apply lifecycle.
Every transform here satisfies the Transform
protocol — a single apply method. Transforms that learn state from data
(Standardize, MinMaxScale) additionally satisfy
Fittable and raise
NotFittedError if used before fit.
Because the protocols are structural, Pipeline happily
composes your own transforms alongside the built-in ones — no base class to
inherit from, no registry to join:
from dataclasses import dataclass
from mypackage import Series, chain, Standardize
@dataclass(frozen=True, slots=True)
class Square:
def apply(self, series: Series) -> list[float]:
return [value**2 for value in series]
pipeline = chain(Standardize(), Square())
Standardize
dataclass
¶
Centre a series on zero and scale it to unit standard deviation.
zᵢ = (xᵢ − x̄) / s, with x̄ the mean and s the standard deviation.
The mean and standard deviation are learned by fit and reused by every
later apply, which is what makes this safe to fit on a training split and
apply to a held-out one.
Attributes:
| Name | Type | Description |
|---|---|---|
ddof |
int
|
Delta degrees of freedom for the standard deviation. |
Examples:
>>> scaler = Standardize().fit([10.0, 12.0, 14.0])
>>> [round(value, 4) for value in scaler.apply([10.0, 12.0, 14.0])]
[-1.0, 0.0, 1.0]
The learned statistics carry over to unseen data:
inverse round-trips:
fit
¶
fit(series: Series) -> Self
Learn the mean and standard deviation of series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The reference observations. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
EmptySeriesError
|
If |
ValidationError
|
If |
Source code in src/mypackage/transforms.py
apply
¶
apply(series: Series) -> list[float]
Standardise series with the learned statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The observations to transform. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
A new list of standardised values. |
Raises:
| Type | Description |
|---|---|
NotFittedError
|
If |
Source code in src/mypackage/transforms.py
inverse
¶
inverse(series: Series) -> list[float]
Map standardised values back to the original scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
Standardised observations. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
A new list on the original scale. |
Raises:
| Type | Description |
|---|---|
NotFittedError
|
If |
Source code in src/mypackage/transforms.py
MinMaxScale
dataclass
¶
Linearly rescale a series into feature_range.
yᵢ = a + (b − a) (xᵢ − min x) / (max x − min x),
with (a, b) the feature_range.
Attributes:
| Name | Type | Description |
|---|---|---|
feature_range |
tuple[float, float]
|
Target |
Examples:
>>> MinMaxScale().fit_apply([0.0, 5.0, 10.0])
[0.0, 0.5, 1.0]
>>> MinMaxScale(feature_range=(-1.0, 1.0)).fit_apply([0.0, 5.0, 10.0])
[-1.0, 0.0, 1.0]
fit
¶
fit(series: Series) -> Self
Learn the minimum and maximum of series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The reference observations. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
EmptySeriesError
|
If |
ValidationError
|
If |
Source code in src/mypackage/transforms.py
apply
¶
apply(series: Series) -> list[float]
Rescale series with the learned bounds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The observations to transform. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
A new list of rescaled values. |
Raises:
| Type | Description |
|---|---|
NotFittedError
|
If |
Source code in src/mypackage/transforms.py
Clip
dataclass
¶
Clamp every value into [lower, upper].
Stateless: fit is a no-op that returns self, so Clip drops into a
Pipeline next to fitted transforms without special
casing.
Attributes:
| Name | Type | Description |
|---|---|---|
lower |
float | None
|
Lower bound, or |
upper |
float | None
|
Upper bound, or |
Examples:
>>> Clip(lower=0.0).apply([-2.0, 0.5, 3.0])
[0.0, 0.5, 3.0]
>>> Clip(lower=0.0, upper=1.0).apply([-2.0, 0.5, 3.0])
[0.0, 0.5, 1.0]
fit
¶
apply
¶
apply(series: Series) -> list[float]
Clamp every value of series into the configured bounds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The observations to clamp. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
A new list of clamped values. |
Source code in src/mypackage/transforms.py
MovingAverage
dataclass
¶
MovingAverage(window: int, padding: Padding | str = EDGE)
Transform adapter around moving_average.
Stateless, so it composes freely inside a
Pipeline.
Attributes:
| Name | Type | Description |
|---|---|---|
window |
int
|
Number of samples averaged per output point. |
padding |
Padding | str
|
Boundary strategy, see |
Examples:
fit
¶
fit(series: Series) -> MovingAverage
Pipeline
dataclass
¶
Pipeline(steps: list[Transform] = list())
Apply a sequence of transforms left to right.
Fitting is sequential: each step is fitted on the output of the previous one, exactly as it will see the data at apply time.
Attributes:
| Name | Type | Description |
|---|---|---|
steps |
list[Transform]
|
The transforms to apply, in order. |
Examples:
>>> pipeline = Pipeline([Standardize(), Clip(lower=-1.0, upper=1.0)])
>>> [round(v, 4) for v in pipeline.fit_apply([10.0, 12.0, 14.0, 40.0])]
[-0.6385, -0.4966, -0.3547, 1.0]
Pipelines compose with |, and nest:
>>> combined = pipeline | MovingAverage(window=3)
>>> len(combined)
3
>>> [round(v, 4) for v in combined.fit_apply([10.0, 12.0, 14.0, 40.0])]
[-0.5912, -0.4966, 0.0495, 0.5484]
Empty pipelines are the identity:
fit
¶
fit(series: Series) -> Self
Fit every step in turn on the output of the previous step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The reference observations. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src/mypackage/transforms.py
apply
¶
apply(series: Series) -> list[float]
Apply every step in turn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series
|
The observations to transform. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
A new list holding the output of the final step. |
Raises:
| Type | Description |
|---|---|
NotFittedError
|
If any stateful step has not been fitted. |
Source code in src/mypackage/transforms.py
chain
¶
Build a Pipeline from positional transforms.
A small convenience over Pipeline([...]) that reads better inline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*transforms
|
Transform
|
Transforms to apply, in order. |
()
|
Returns:
| Type | Description |
|---|---|
Pipeline
|
A new pipeline. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If any argument does not implement |
Examples:
>>> pipeline = chain(MinMaxScale(), MovingAverage(window=3))
>>> [round(v, 4) for v in pipeline.fit_apply([0.0, 5.0, 10.0])]
[0.1667, 0.5, 0.8333]