CodeBlanks Logo Icon CodeBlanks

ColumnTransformer

ColumnTransformer applies different transforms to different columns.

ColumnTransformer

In real tables columns need different processing: numbers are scaled, categories one-hot encoded. ColumnTransformer applies a separate transformer to each column group and concatenates the results side by side:

from sklearn.compose import ColumnTransformer
ct = ColumnTransformer([
    ("sayi", StandardScaler(), ["yas", "gelir"]),
    ("kat", OneHotEncoder(handle_unknown="ignore"), ["sehir"]),
])
Z = ct.fit_transform(df)   # 2 scaled + as many 0/1 columns as cities

Columns can be given by pandas names or integer positions.

A full preprocessing chain

Each column group can have its own sub-pipeline; the whole structure is gathered with the model into a single pipeline:

sayisal = make_pipeline(SimpleImputer(strategy="median"), StandardScaler())
kategorik = make_pipeline(SimpleImputer(strategy="most_frequent"),
                          OneHotEncoder(handle_unknown="ignore"))
ct = ColumnTransformer([("sayi", sayisal, sayi_sutunlar),
                        ("kat", kategorik, kat_sutunlar)])
model = make_pipeline(ct, LogisticRegression())

get_feature_names_out() shows what each column represents after the transformation.

Practice Transform a mixed table

Build a ColumnTransformer processing the yas and gelir columns with StandardScaler and the sehir column with OneHotEncoder. Print the shape of the fit_transform result, then the get_feature_names_out() list.

Starter code

model.py
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder

df = pd.DataFrame({
    "yas": [25, 32, 47, 51],
    "gelir": [3000, 4500, 8000, 6000],
    "sehir": ["Ankara", "İzmir", "Ankara", "Bursa"],
})

# buraya yaz

Sample solution

model.py
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder

df = pd.DataFrame({
    "yas": [25, 32, 47, 51],
    "gelir": [3000, 4500, 8000, 6000],
    "sehir": ["Ankara", "İzmir", "Ankara", "Bursa"],
})

ct = ColumnTransformer([("sayi", StandardScaler(), ["yas", "gelir"]), ("kat", OneHotEncoder(), ["sehir"])])
Z = ct.fit_transform(df)
print(Z.shape)
print(list(ct.get_feature_names_out()))

Expected output

(4, 5)
['sayi__yas', 'sayi__gelir', 'kat__sehir_Ankara', 'kat__sehir_Bursa', 'kat__sehir_İzmir']

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does ColumnTransformer do by default to columns not named in the list?

  • Scales them
  • Errors
  • Drops them (remainder="drop") Correct answer
  • Passes them through unchanged

Explanation: They can be kept with remainder="passthrough".

2 Keep the columns that aren't named.

Question
ct = ColumnTransformer([...], remainder=____)
Answer
ct = ColumnTransformer([...], remainder="passthrough")

Explanation: The default is "drop"; "passthrough" appends the columns unchanged.

3 Match the parts.

Term Meaning
("sayi", StandardScaler(), [...]) Numeric transformation
("kat", OneHotEncoder(), [...]) Categorical transformation
remainder Remaining columns
get_feature_names_out New column names

All lessons in Intermediate