Apply imputation to a DataFrame based on the method specified in config.
Supports three strategies:
"weighted": forward-fill then backward-fill gaps, then build a WeightFunction that down-weights training rows near any gap. Rows inside a gap receive weight 0; the penalty window controls how far the zero-weight zone extends. If config.imputation_window_size is set, that explicit width is respected. Otherwise the width is derived from max(config.lags_consider). An explicitly shorter width emits a warning because positive-weight rows may then use imputed predictors.
"weighted_interp": like "weighted" but uses time-interpolation (via LinearlyInterpolateTS) for the fill step instead of ffill/bfill. Boundary NaNs that interpolation cannot bracket are resolved by ffill/bfill as a final fallback. The pre-fill NaN mask drives the same rolling penalty-window zero-weight construction as "weighted". Intended for use with target_corruption_policy="heal", where physically-impossible dropouts should be bridged smoothly rather than step-filled.
A diagnostic summary (NaN count before and after imputation) is always written to the logger.
Configuration object that must expose: - imputation_method (str): "weighted", "weighted_interp", or "linear". - targets (list[str]): column names to interpolate ("linear" method only; also accepted as the explicit targets keyword argument which takes precedence). - imputation_window_size (int \| None): explicit penalty width; None derives it from lags_consider. - lags_consider (list[int]): candidate lags used to derive the default penalty width. - window_size (int): compatibility fallback when the config does not expose lags_consider.