Source code for pretab.transformers.temporal.rolling_stats

import numpy as np
from sklearn.utils.validation import check_is_fitted

from ...core.base import BasePreTabTransformer
from ...core.exceptions import InsufficientSamplesError, invalid_param_error


[docs] class RollingStatsTransformer(BasePreTabTransformer): """Compute rolling-window statistics over time-series inputs. A sliding window of fixed size is moved across each feature and the requested summary statistics are computed within each window. Parameters ---------- window_size : int, default=5 Number of consecutive observations in each rolling window. stats : tuple of str, default=("mean", "std") Statistics to compute. Any of ``"mean"``, ``"std"``, ``"min"``, ``"max"``. Notes ----- Using a sliding window of size ``window_size`` yields ``n_samples - window_size + 1`` output rows. Each requested statistic adds one column per input feature. This is a **standalone time-series utility**. It intentionally changes the row count and assumes the rows are ordered in time, so it does not satisfy the row-count-preserving contract that :class:`~sklearn.compose.ColumnTransformer` (and therefore :class:`~pretab.preprocessor.Preprocessor`) require. Apply it directly to an ordered array rather than routing it through the preprocessing pipeline. Examples -------- >>> import numpy as np >>> from pretab.transformers import RollingStatsTransformer >>> X = np.arange(10).reshape(-1, 1).astype(float) >>> transformer = RollingStatsTransformer(window_size=3, stats=("mean", "std")) >>> transformer.fit_transform(X).shape (8, 2) """ _allow_nan = False _feature_suffix_value = "roll"
[docs] def __init__(self, window_size=5, stats=("mean", "std")): self.window_size = window_size self.stats = stats
def fit(self, X, y=None): X = self._validate(X, reset=True) if X.shape[0] < self.window_size: raise InsufficientSamplesError("window_size must be less than number of samples.") return self def transform(self, X): check_is_fitted(self, "n_features_in_") X = self._validate(X, reset=False) n_samples = X.shape[0] if n_samples < self.window_size: raise InsufficientSamplesError("Insufficient samples for the given window size.") results = [] for stat in self.stats: rolled = np.lib.stride_tricks.sliding_window_view(X, self.window_size, axis=0) if stat == "mean": stat_val = rolled.mean(axis=2) elif stat == "std": stat_val = rolled.std(axis=2) elif stat == "min": stat_val = rolled.min(axis=2) elif stat == "max": stat_val = rolled.max(axis=2) else: raise invalid_param_error( type(self).__name__, "stats", stat, "each stat must be one of 'mean', 'std', 'min', 'max'", valid={"mean", "std", "min", "max"}, ) results.append(stat_val) return np.hstack(results) def _output_sizes(self) -> list[int]: return [len(self.stats)] * self.n_features_in_