Encoding categories

OneHotEncoder and ColumnTransformer for mixed types.

Logistic regression wants numbers. City names (Nairobi) need a numeric encoding. OneHotEncoder makes one column per category. ColumnTransformer applies different transformers to numeric vs categorical columns.

Goal

One-hot encode cities, then build a ColumnTransformer for a mixed kiosk table.

OneHotEncoder

from sklearn.preprocessing import OneHotEncoder

cities = np.array(["Nairobi", "Mombasa", "Nairobi", "Kisumu"]).reshape(-1, 1)
enc = OneHotEncoder(sparse_output=False, handle_unknown="ignore")
out = enc.fit_transform(cities)
print(enc.get_feature_names_out(["city"]))
print(out)

handle_unknown="ignore" turns an unseen city on test into a row of zeros instead of an error.

ColumnTransformer

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa", "Mombasa", "Kisumu", "Kisumu"],
        "units": [12, 7, 9, 4, 11, 3],
        "price": [10.5, 22.0, 10.5, 10.5, 22.0, 10.5],
        "high": [1, 1, 0, 0, 1, 0],
    }
)
X = df[["city", "units", "price"]]
y = df["high"]
prep = ColumnTransformer(
    [
        ("cat", OneHotEncoder(sparse_output=False, handle_unknown="ignore"), ["city"]),
        ("num", StandardScaler(), ["units", "price"]),
    ]
)
Xt = prep.fit_transform(X)
print(prep.get_feature_names_out())
print(Xt.round(2))
print("y", y.tolist())

Remainder columns are dropped by default. List every feature you want to keep.

Tip

Trees can use OrdinalEncoder (integer codes). Linear models prefer one-hot so “Kisumu = 2” is not treated as twice Nairobi.