Padronizando categorias inconsistentes
Normalize colunas de categorias em texto livre mapeando aliases, corrigindo erros de digitação com correspondência aproximada e impondo uma lista canônica.
Padronizando categorias inconsistentes é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
Partes desta aula ainda não foram traduzidas e aparecem em inglês.
The Problem of Inconsistent Categories
When category data is entered by humans, the same concept appears under many different spellings: Electronics, electronics, ELECTRONICS, Electronicss. A groupby on this column produces dozens of tiny groups instead of one meaningful group. Standardising categories into a canonical list is one of the most important cleaning steps before any aggregation or machine learning feature creation.
import pandas as pd
df = pd.read_csv('products.csv')
print(df['category'].value_counts().head(20))Normalising Case and Whitespace
The first and easiest standardisation step is normalising case and whitespace. Apply .str.strip().str.lower() to remove leading/trailing spaces and convert everything to lowercase before any other comparison. This single step collapses many variants: Electronics, electronics, and ' Electronics ' all become electronics after normalisation.
df['category_clean'] = df['category'].str.strip().str.lower()
print('Before:', df['category'].nunique())
print('After:', df['category_clean'].nunique())Mapping Aliases with a Dict
After case normalisation, many variants are still distinct due to abbreviations, synonyms, or legacy names. Build an alias mapping dictionary where keys are variant spellings and values are the canonical form. Apply it with df['category_clean'].map(alias_map).fillna(df['category_clean']) — the fillna preserves values not in the dictionary rather than replacing them with NaN.
alias_map = {
'elect': 'electronics',
'elec': 'electronics',
'tech': 'electronics',
'clothing': 'apparel',
'clothes': 'apparel',
'garments': 'apparel'
}
df['category_clean'] = df['category_clean'].map(alias_map).fillna(df['category_clean'])
print(df['category_clean'].value_counts().head())Using str.replace for Pattern Fixes
Some category names have consistent formatting errors like double spaces or trailing numbers. Use .str.replace() with a regular expression to fix these patterns across all rows at once. For example, .str.replace(r'\s+', ' ', regex=True) collapses multiple spaces into one, and .str.replace(r'\d+$', '', regex=True) strips trailing digits from category names.
df['category_clean'] = (
df['category_clean']
.str.replace(r'\s+', ' ', regex=True) # collapse spaces
.str.replace(r'\d+$', '', regex=True) # strip trailing numbers
.str.strip()
)
print(df['category_clean'].value_counts())Fuzzy Matching with difflib
When typos are unpredictable, use fuzzy matching to find the closest canonical category for each variant. Python's built-in difflib.get_close_matches() returns the best matches from a list of valid categories based on string similarity. Apply it as a helper function via df['category'].apply() to resolve variants that map() alone cannot catch.
from difflib import get_close_matches
CANONICAL = ['electronics', 'apparel', 'home', 'sports', 'beauty']
def fuzzy_fix(val):
matches = get_close_matches(str(val).lower().strip(), CANONICAL, n=1, cutoff=0.7)
return matches[0] if matches else val
df['category_fuzzy'] = df['category_clean'].apply(fuzzy_fix)
print(df[['category_clean', 'category_fuzzy']].head(10))Building a Canonical Category List
Define your canonical categories explicitly rather than inferring them from the data. A hard-coded list forces every value through a validation gate; anything not in the list is flagged as unknown. Maintain the canonical list in a config file or a separate DataFrame column so it is easy to update when the business adds a new product category without touching the cleaning code.
CANONICAL_CATEGORIES = {
'electronics', 'apparel', 'home', 'sports',
'beauty', 'food', 'toys', 'automotive'
}
df['is_known_category'] = df['category_fuzzy'].isin(CANONICAL_CATEGORIES)
unknown = df[~df['is_known_category']]['category_fuzzy'].unique()
print('Unknown categories remaining:', unknown)Handling Unknown Categories
Unknown categories that do not match any canonical value after fuzzy fixing should be grouped under an Other label rather than dropped, so you do not silently lose rows. Set them to 'other' with np.where() or a simple conditional assignment. Log how many rows were mapped to 'other' and review them for patterns that might warrant a new canonical category.
import numpy as np
df['category_final'] = np.where(
df['category_fuzzy'].isin(CANONICAL_CATEGORIES),
df['category_fuzzy'],
'other'
)
print(df['category_final'].value_counts())Enforcing a Categorical Dtype
After standardisation, convert the clean category column to a Pandas Categorical dtype with an explicit list of valid categories. This enforces the schema: any attempt to assign an invalid category raises an error. It also reduces memory by storing category strings as integer codes internally, and speeds up groupby operations on large DataFrames.
df['category_final'] = pd.Categorical(
df['category_final'],
categories=list(CANONICAL_CATEGORIES) + ['other']
)
print(df['category_final'].dtype)
print(df['category_final'].cat.categories)Validating the Clean Column
After all standardisation steps, run a final validation: assert that no value outside the canonical set exists in the cleaned column. Use assert df['category_final'].isin(valid_set).all(). Place this assertion at the end of the cleaning function so it runs every time the pipeline executes, catching regressions when new raw data contains previously unseen category labels.
valid_set = set(CANONICAL_CATEGORIES) | {'other'}
assert df['category_final'].isin(valid_set).all(), 'Invalid category found'
print('All categories valid. Distribution:')
print(df['category_final'].value_counts())Tracking the Standardisation Changes
Build a diff table showing the original value and its cleaned replacement for every row that changed. This audit trail lets data owners review and approve or reject specific mappings. Use a boolean mask to select changed rows and compare the original and final columns side by side. Export the diff as a CSV for non-technical stakeholders to review.
changed = df['category'] != df['category_final']
diff_table = df[changed][['category', 'category_final']].drop_duplicates()
diff_table.columns = ['original', 'mapped_to']
print(f'Unique mappings applied: {len(diff_table)}')
print(diff_table)Saving the Standardised Dataset
Replace the original messy category column with the standardised one and drop intermediate working columns before saving. Store the alias mapping dictionary and the fuzzy-fix cutoff threshold in the pipeline config so the standardisation is fully reproducible. A cleaning run two months later on a new data dump should produce identical results for the same input values.
df_out = df.drop(columns=['category_clean', 'category_fuzzy', 'is_known_category'])
df_out = df_out.rename(columns={'category_final': 'category'})
df_out.to_parquet('products_clean.parquet', index=False)
print('Saved. Category distribution:')
print(df_out['category'].value_counts())Quick Check
Test your understanding of Data Analysis concepts from this lesson.
Lesson Recap
In this lesson you learned: normalising case and whitespace as a first standardisation step, mapping aliases and applying fuzzy matching for typo correction, and enforcing a canonical category list with Categorical dtype and assertions. Next up we explore schema validation and runtime assertions to guard every pipeline stage.
Perguntas Frequentes
A aula “Padronizando categorias inconsistentes” é grátis?
Sim — o texto completo de “Padronizando categorias inconsistentes” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
O que vou aprender em “Padronizando categorias inconsistentes”?
Normalize colunas de categorias em texto livre mapeando aliases, corrigindo erros de digitação com correspondência aproximada e impondo uma lista canônica. Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Pandas & NumPy Academy?
Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Padronizando categorias inconsistentes”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Pandas & NumPy Academy?
Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Detectando e removendo duplicatas
- Detecção e tratamento de valores discrepantes
- Padronizando categorias inconsistentes
- Validação de esquema e asserções