Data Science Categorical Data
Categorical data needs to be converted into numbers before most machine learning models can use it, and the right encoding depends on whether the categories have a natural order.
Why Categories Can't Be Used As-Is
Most scikit-learn models only accept numeric input. A column like 'city' with values Chicago, Paris, and Tokyo, or 'size' with values Small, Medium, and Large, has to be transformed into numbers first. How you do that transformation matters a lot: pick the wrong encoding and you can accidentally tell the model that categories have a mathematical relationship that doesn't exist.
Nominal vs Ordinal Categories
Nominal categories have no inherent order: colors, cities, and payment methods are all nominal, since 'red' isn't mathematically greater or less than 'blue'. Ordinal categories do have a meaningful order: a satisfaction rating of Low, Medium, High, or a shirt size of Small, Medium, Large, XL clearly rank from lower to higher. This distinction decides which encoding to use.
- Nominal data (no order) -> one-hot / dummy encoding, e.g. pandas.get_dummies() or OneHotEncoder.
- Ordinal data (has order) -> ordinal encoding, e.g. OrdinalEncoder or a manual mapping, preserving rank order as integers.
Example: One-hot encoding nominal data with pandas
import pandas as pd
df = pd.DataFrame({
'city': ['Chicago', 'Paris', 'Tokyo', 'Paris'],
'sales': [200, 150, 300, 180]
})
# get_dummies creates one binary column per category
encoded = pd.get_dummies(df, columns=['city'])
print(encoded)
# sales city_Chicago city_Paris city_Tokyo
# 0 200 True False False
# 1 150 False True False
# 2 300 False False True
# 3 180 False True FalseOrdinal Encoding When Order Matters
When categories do have a real ranking, encoding them as ordered integers is not only safe, it's useful: it lets the model learn a single coefficient that captures the increasing (or decreasing) effect of moving up a level, instead of learning a separate, unrelated coefficient per category as one-hot encoding would.
Example: Ordinal encoding with scikit-learn
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder
df = pd.DataFrame({
'satisfaction': ['Low', 'High', 'Medium', 'Medium', 'Low']
})
# Explicitly list the true rank order, lowest to highest
encoder = OrdinalEncoder(categories=[['Low', 'Medium', 'High']])
df['satisfaction_encoded'] = encoder.fit_transform(df[['satisfaction']])
print(df)
# satisfaction satisfaction_encoded
# 0 Low 0.0
# 1 High 2.0
# 2 Medium 1.0
# 3 Medium 1.0
# 4 Low 0.0As a quick rule of thumb: if you can't answer 'is category A definitively more or less than category B?', treat the feature as nominal and one-hot encode it. If you can rank every category confidently, ordinal encoding usually produces a simpler and more effective model.
Exercise: Data Science Categorical Data
What is categorical data?