Materialize

Point-in-time-correct feature materialization.

Two paths that must (and are tested to) agree:

  • materialize() — batch: one matrix for many origins at once, indexed by (asof, target_time). This is what makes the vectorized execution mode fast: all origins in one shot, masked by availability.

  • materialize_observation() — one origin, built purely from the observation’s view API (which already enforces availability). Used by FeaturePredictor in event mode.

Both produce NaN wherever a feature would need data outside the origin’s information set — never a peeked value.

emflow.features.materialize.materialize(feed: DataFeed, features: Sequence[Lag | Rolling | ForecastField | Calendar], origins) DataFrame[source]

Feature matrix for all origins, indexed by (asof, target_time).

emflow.features.materialize.materialize_observation(view: TimeView, features: Sequence[Lag | Rolling | ForecastField | Calendar], target_index: DatetimeIndex) DataFrame[source]

Feature matrix for one origin, using only what the view serves.

The view’s availability enforcement is the masking: a lag reaching past the information set simply isn’t in view.history() and reindexes to NaN. Index matches materialize()’s rows for the same origin.

emflow.features.materialize.supervised_frame(feed: DataFeed, features: Sequence[Lag | Rolling | ForecastField | Calendar], origins, target_field: str, target_column=None)[source]

(X, y) for supervised training over training-period origins.

y reads actuals at target times directly — only ever call this on origins whose targets lie in the training split. Evaluation goes through the environment, which cannot leak.