Many scikit-learn estimators expect numeric feature matrices, while source tables often carry labels such as city and plan names. OneHotEncoder gives each learned category its own binary column without inventing an order between labels.
The encoder should learn categories from training rows only. Reuse that fitted object for validation and prediction data so output columns stay in the same order and held-out categories do not influence the model's feature space.
Setting handle_unknown="ignore" emits zeros for every output column belonging to an unseen category instead of raising an error. Setting sparse_output=False makes this small matrix readable, but high-cardinality production data normally benefits from the default sparse output.
from sklearn.preprocessing import OneHotEncoder feature_names = ["city", "plan"] training_rows = [ ["Paris", "free"], ["Tokyo", "paid"], ["Paris", "paid"], ["London", "free"], ] new_rows = [["Berlin", "paid"]]
encoder = OneHotEncoder(handle_unknown="ignore", sparse_output=False) encoded_training = encoder.fit_transform(training_rows).astype(int) output_features = encoder.get_feature_names_out(feature_names)
encoded_new = encoder.transform(new_rows).astype(int) print("Features:", ", ".join(output_features)) print("Training shape:", encoded_training.shape) print("New row:", encoded_new) assert encoded_new.tolist() == [[0, 0, 0, 0, 1]]
$ python3 one_hot_categories.py Features: city_London, city_Paris, city_Tokyo, plan_free, plan_paid Training shape: (4, 5) New row: [[0 0 0 0 1]]
The first three positions belong to the learned city categories, so the unseen Berlin value produces zeros there. The final 1 belongs to plan_paid, which was learned from the training rows.