100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Encoding Categorical Variables

Learn how to convert non-numeric categories into numeric representations models can use, and when to choose one-hot, ordinal, or target encoding.

Feature EngineeringBeginner8 min readJul 8, 2026
Analogies

Encoding Categorical Variables

Most machine learning algorithms operate on numbers, but real-world data is full of categorical variables — colors, city names, product types, education levels — that have no inherent numeric value. Encoding is the process of converting these categories into a numeric representation a model can consume, and the choice of encoding scheme materially affects what the model can learn, because a poor encoding can either invent a false ordering where none exists or explode the feature space into an unmanageable number of columns.

🏏

Cricket analogy: A model can't directly consume 'bowling style: leg-spin' as text; encoding turns it into numbers, but encoding leg-spin, off-spin, and pace as 1, 2, 3 would falsely imply pace is 'three times' leg-spin, a trap encoding must avoid.

One-Hot Encoding

One-hot encoding creates a new binary (0/1) column for each category, with exactly one column set to 1 for each row. It makes no assumption about ordering between categories, which is correct for nominal variables like 'city' or 'color' where no category is inherently 'greater' than another. Its main drawback is dimensionality: a categorical column with 500 unique cities becomes 500 new columns, which can make models slower to train and, for tree-based models, dilute the signal across many sparse columns. Rare categories are often grouped into an 'other' bucket first to control this explosion.

🏏

Cricket analogy: One-hot encoding a 'home ground' column with 40 different stadiums creates 40 binary columns, one lit up per match, correctly implying no stadium outranks another; but with 500 grounds tracked globally the feature space balloons unmanageably, so rarely used venues get grouped into 'other.'

Ordinal, Label, and Target Encoding

Ordinal encoding assigns integers according to a meaningful order (e.g., 'low'=0, 'medium'=1, 'high'=2), which is appropriate only when categories genuinely have a rank — applying it to unordered categories like 'city' would falsely imply, say, that 'Chicago' (2) is 'twice' some other city (1), misleading distance-based and linear models. Label encoding is similar mechanically but is typically applied to the target variable in classification, or used internally by tree-based libraries that can handle arbitrary integer codes without assuming order. Target encoding replaces each category with a statistic (commonly the mean of the target variable) computed from that category, which is powerful for high-cardinality columns but must be computed using only training-fold data (via nested/out-of-fold cross-validation) to avoid leaking target information into the encoding itself.

🏏

Cricket analogy: Ordinal encoding a bowler's 'pace category' as slow=0, medium=1, fast=2 is valid since fast genuinely outranks slow, but label encoding a team name like 'Royals'=1 is only safe for tree models; target encoding replaces a venue with its average runs-scored, computed strictly from training-fold matches to avoid leaking future results.

python
import pandas as pd
from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder

df = pd.DataFrame({
    'city': ['NYC', 'LA', 'NYC', 'Chicago'],
    'education': ['high_school', 'bachelors', 'masters', 'bachelors'],
})

# Nominal variable -> one-hot encoding (no assumed order)
ohe = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
city_encoded = ohe.fit_transform(df[['city']])
print(ohe.get_feature_names_out(), '\n', city_encoded)

# Ordinal variable -> ordinal encoding, with an explicit order
edu_order = [['high_school', 'bachelors', 'masters', 'phd']]
oe = OrdinalEncoder(categories=edu_order, handle_unknown='use_encoded_value', unknown_value=-1)
df['education_encoded'] = oe.fit_transform(df[['education']])
print(df[['education', 'education_encoded']])

Pandas' pd.get_dummies() is functionally similar to scikit-learn's OneHotEncoder for quick exploratory work, but OneHotEncoder is generally preferred in production pipelines because it remembers the categories seen during fit and can consistently handle unseen categories at prediction time via handle_unknown='ignore'.

Never label-encode a nominal (unordered) feature and feed it directly into a linear or distance-based model — the arbitrary integers you assign (e.g., 'Paris'=0, 'Tokyo'=1, 'Cairo'=2) impose a false numeric ordering and false distances between categories that the model will treat as meaningful, degrading performance.

  • Categorical encoding converts non-numeric categories into numbers that models can use.
  • One-hot encoding creates a binary column per category and is correct for unordered (nominal) variables.
  • Ordinal encoding uses meaningful integer ordering and should only be used for genuinely ranked categories.
  • Target encoding replaces categories with target-derived statistics, useful for high-cardinality columns but leakage-prone if not done via out-of-fold computation.
  • High-cardinality categorical columns can cause one-hot encoding to explode dimensionality; grouping rare categories helps.
  • Applying label/ordinal encoding to nominal data misleads linear and distance-based models by implying a false order.

Practice what you learned

Was this page helpful?

Topics covered

#Python#MachineLearningBasicsStudyNotes#MachineLearning#EncodingCategoricalVariables#Encoding#Categorical#Variables#One#StudyNotes#SkillVeris