Skip to content

fix(impute): never impute declared id_columns or target_column - #423

Merged
kevincostner17 merged 3 commits into
mainfrom
fix/impute-skip-id-target
Sep 15, 2026
Merged

kevincostner17 merged 3 commits into
mainfrom
fix/impute-skip-id-target

Conversation

@kevincostner17

Copy link
Copy Markdown
Contributor

Summary

Explicit imputation filled the declared id_columns and target_column, contradicting the documented safe default (README: "never imputes an identifier, modifies a target column"; docs/cleaning-engine.md, trust-claims.md). Only context-protected columns were being skipped.

With impute="mean" / "median" and id_columns=("customer_id",), target_column="churn", both columns had their missing cells filled — corrupting identifiers and leaking into the target. Defaults are unaffected because imputation is off by default.

Change

  • impute_missing now skips the declared id_columns and target_column for the simple mean/median/mode/auto strategies, in addition to the existing context-protected skip.
  • Declared names resolve after column renaming, reusing the guard's _match_columns (exact, then snake_case), so "Customer ID" still matches customer_id.
  • The report records skipped: identifier column / skipped: target column only when a value would actually have changed.
  • An impute_strategy entry naming one of these columns is ignored with a warning.
  • MissForest is unchanged: it already gates target/id roles with its own audited fallback action, so declared roles stay in its candidate list (and can serve as features for other columns). This keeps test_missforest_respects_target_id_text_and_high_missingness_gates passing.

Tests

New cases in tests/test_missing.py: id/target never imputed across mean/median/mode/auto; an impute_strategy on the target ignored with a warning; a renamed declared id; no skip note when there is nothing to fill; and MissForest never imputing a declared target.

Verification

  • tests/test_missing.py, test_missforest_imputation.py, test_missforest_nullable_int.py, test_impute_column_validation.py, test_engine_missing.py, test_properties.py, test_regressions.py, test_api.py: 145 passed on Python 3.12 / pandas 2.3.3 and Python 3.9 / pandas 1.5.3.
  • ruff check: clean. (mypy runs in CI's quality-fast lane; a local run is blocked by numpy 2.5 stub syntax.)

Found by the production-readiness test campaign (lane L5, finding FDC-L5-012). The companion outlier fix (outliers="clip" clipping the same columns) is handled separately.

Explicit imputation (impute=/impute_strategy=) filled the declared
id_columns and target_column, contradicting the documented safe default
('never imputes an identifier, modifies a target column'). Only
context-protected columns were skipped.

Skip the declared identifier and target columns in the simple mean/median/
mode strategies too, resolving names after renaming like the protected-column
guard. Report 'skipped: identifier column' / 'skipped: target column' when a
value would have changed, and warn when an impute_strategy entry names one of
them. MissForest already gates these roles with its own audited action, so its
candidate list is unchanged. Defaults are unaffected (impute is off).
@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fe68e467-a757-4dc5-b004-6259748ce617


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

FreshData benchmark report — performance

  • freshdata: ?
  • python: ?
  • platform: ?
fixture n_rows n_cols p50 s p95 s peak MB repair % false-repair % preserve % trust monotonic export %

Authored-code reduction (Metric 6)

@kevincostner17
kevincostner17 merged commit e2bdbac into main Sep 15, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant