scikit-learn
ColumnTransformer
data imputation
data normalization
machine learning

Accessing the values used to impute and normalize new data based upon scikit-learn ColumnTransformer

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When you deploy a model, new data must be transformed using the exact imputation and scaling parameters learned during training. With scikit-learn ColumnTransformer, those learned values are stored inside fitted sub-transformers. This guide shows how to inspect them safely and reuse the fitted pipeline for consistent inference.

Build a Fitted ColumnTransformer

python
1import pandas as pd
2from sklearn.compose import ColumnTransformer
3from sklearn.impute import SimpleImputer
4from sklearn.pipeline import Pipeline
5from sklearn.preprocessing import StandardScaler, OneHotEncoder
6
7X = pd.DataFrame({
8    "age": [20, 35, None, 50],
9    "income": [40000, None, 60000, 80000],
10    "city": ["A", "B", "A", None],
11})
12
13num_cols = ["age", "income"]
14cat_cols = ["city"]
15
16num_pipe = Pipeline([
17    ("imputer", SimpleImputer(strategy="median")),
18    ("scaler", StandardScaler()),
19])
20
21cat_pipe = Pipeline([
22    ("imputer", SimpleImputer(strategy="most_frequent")),
23    ("encoder", OneHotEncoder(handle_unknown="ignore")),
24])
25
26ct = ColumnTransformer([
27    ("num", num_pipe, num_cols),
28    ("cat", cat_pipe, cat_cols),
29])
30
31ct.fit(X)

After fit, the imputer statistics and scaler parameters are available.

Access Imputation and Scaling Values

Use named_transformers_ to access fitted branches.

python
1num_fitted = ct.named_transformers_["num"]
2cat_fitted = ct.named_transformers_["cat"]
3
4num_imputer = num_fitted.named_steps["imputer"]
5num_scaler = num_fitted.named_steps["scaler"]
6cat_imputer = cat_fitted.named_steps["imputer"]
7
8print("Numeric imputation values:", num_imputer.statistics_)
9print("Scaler mean:", num_scaler.mean_)
10print("Scaler scale:", num_scaler.scale_)
11print("Categorical imputation value:", cat_imputer.statistics_)

These values are exactly what the transformer uses for new data.

Transform New Data Consistently

Do not recompute imputation or scaling from incoming inference data. Reuse the fitted object.

python
1X_new = pd.DataFrame({
2    "age": [None, 44],
3    "income": [70000, None],
4    "city": ["B", "C"],
5})
6
7X_new_t = ct.transform(X_new)
8print(X_new_t.shape)

If you have unseen categories, handle_unknown="ignore" prevents runtime failures.

Map Statistics Back to Column Names

For numeric transformers, align statistics with original column order.

python
1for col, stat in zip(num_cols, num_imputer.statistics_):
2    print(col, "imputed with", stat)
3
4for col, mean, scale in zip(num_cols, num_scaler.mean_, num_scaler.scale_):
5    print(col, "mean", mean, "scale", scale)

This is useful for model cards and audit reports.

Persist and Reload for Inference

Save the fitted transformer with joblib to guarantee reproducible preprocessing.

python
1import joblib
2
3joblib.dump(ct, "preprocessor.joblib")
4loaded_ct = joblib.load("preprocessor.joblib")
5
6print(loaded_ct.transform(X_new).shape)

Persisting the fitted object prevents accidental drift between training and serving code paths.

Full Pipeline with Model

In production, fit preprocessing and model together in one pipeline.

python
1from sklearn.linear_model import LogisticRegression
2from sklearn.pipeline import Pipeline
3
4model = Pipeline([
5    ("preprocess", ct),
6    ("clf", LogisticRegression(max_iter=500)),
7])

This reduces mismatch risk because transform and predict share one serialized artifact.

Inspect Encoded Feature Names

After fitting, feature name output helps map transformed arrays back to original semantics.

python
feature_names = ct.get_feature_names_out()
print(feature_names)

This is especially useful when debugging model coefficients or explaining feature importance.

Access Parameters Through Full Pipeline

In real projects, preprocessing is often wrapped in a pipeline with the model. Access nested objects safely through named steps.

python
1from sklearn.pipeline import Pipeline
2from sklearn.linear_model import LogisticRegression
3
4full = Pipeline([
5    ("preprocess", ct),
6    ("model", LogisticRegression(max_iter=300))
7])
8
9full.fit(X, [0, 1, 0, 1])
10
11pre = full.named_steps["preprocess"]
12num = pre.named_transformers_["num"]
13print(num.named_steps["imputer"].statistics_)

This pattern keeps training and inference artifacts aligned while still exposing interpretability metadata when needed.

Store preprocessing version metadata alongside the serialized artifact so audit and rollback workflows can verify exactly which imputation and scaling statistics were used.

Common Pitfalls

  • Refitting imputer and scaler on inference data instead of reusing trained parameters.
  • Accessing transformer attributes before calling fit.
  • Misreading statistic order by forgetting original numeric column order.
  • Ignoring unknown category behavior in one-hot encoding.
  • Saving model and preprocessor separately without version control of both artifacts.

Summary

  • Fitted ColumnTransformer stores learned imputation and scaling values.
  • Access values through named_transformers_ and nested named_steps.
  • Reuse the same fitted object for all future transformations.
  • Persist preprocessing artifacts to keep training and inference aligned.
  • Bundle preprocessing with the model to reduce deployment drift.

Course illustration
Course illustration

All Rights Reserved.