Cleaning Data
🎧 Focus sounds
Soft beat sounds that many learners like while reading. Pick one, press Play, and keep studying.
Keep the volume low. These sounds are for comfort while studying, not a medical treatment. If you have epilepsy or are sensitive to pulsing sounds, use the background noise only.
In this lesson
Analysts say 80% of the job is cleaning data. Real files have empty cells, the same row twice, numbers stored as text and names typed five different ways. Clean data first, or every answer after it is wrong.
Here’s a messy table, like a real export:
import pandas as pd
import numpy as np
df = pd.DataFrame({
"name": ["Asha", "rahul ", "Meera", "Kabir", "Asha", "Zoya"],
"city": ["Pune", "Surat", None, "Pune", "Pune", "Delhi"],
"marks": [82, np.nan, 90, np.nan, 82, 74],
"fees": ["1,200", "900", "1,500", "1,100", "1,200", "N/A"],
})
print(df)
Output:
name city marks fees
0 Asha Pune 82.0 1,200
1 rahul Surat NaN 900
2 Meera None 90.0 1,500
3 Kabir Pune NaN 1,100
4 Asha Pune 82.0 1,200
5 Zoya Delhi 74.0 N/A
1. Missing values#
First count them, column by column:
print(df.isna().sum())
Output:
name 0
city 1
marks 2
fees 0
dtype: int64
Then decide, column by column: drop the rows, or fill the gaps. Compare both:
df["marks"] = df["marks"].fillna(df["marks"].mean())
df["city"] = df["city"].fillna("Unknown")
print(df[["name", "city", "marks"]])
Output:
name city marks
0 Asha Pune 82.0
1 rahul Surat 82.0
2 Meera Unknown 90.0
3 Kabir Pune 82.0
4 Asha Pune 82.0
5 Zoya Delhi 74.0
The mean of 82, 90, 82 and 74 is 82, so both gaps got 82. df.dropna() would instead remove every row with a gap.
Fill numbers with the mean or median, categories with “Unknown” or the most common value. Drop rows only when very few are missing, or when the missing column is the thing you want to predict.
2. Duplicates#
print(df.duplicated().sum())
df = df.drop_duplicates()
print(len(df))
Output:
1
5
Row 4 was an exact copy of row 0, so it’s gone.
3. Wrong types: numbers stored as text#
fees looks like numbers but is text because of the commas and the “N/A”. Remove the commas, then convert; errors="coerce" turns anything that still isn’t a number into NaN:
df["fees"] = pd.to_numeric(df["fees"].str.replace(",", ""), errors="coerce")
print(df["fees"].tolist())
print(df["fees"].dtype)
Output:
[1200.0, 900.0, 1500.0, 1100.0, nan]
float64
Now you can do maths on fees: df["fees"].sum().
4. Messy text#
"rahul " has a trailing space and a lower-case letter, so it would count as a different person from “Rahul”. The .str methods fix a whole column at once:
df["name"] = df["name"].str.strip().str.title()
print(df["name"].tolist())
Output:
['Asha', 'Rahul', 'Meera', 'Kabir', 'Zoya']
Other handy ones: .str.lower(), .str.upper(), .str.replace("old", "new"), .str.split(",").
5. Rename columns#
df = df.rename(columns={"marks": "score", "fees": "fees_inr"})
print(df.columns.tolist())
Output:
['name', 'city', 'score', 'fees_inr']
A cleaning checklist#
df.info()anddf.isna().sum(): what’s missing, what types are wrong?- Fix types (
pd.to_numeric,pd.to_datetime,astype). - Clean text (
str.strip,str.title). - Handle missing values (
fillnaordropna). - Remove duplicates.
- Check again with
describe(): do min and max look possible?
Quick check
Marks of -5 or 950 in an exam out of 100 aren’t missing, but they’re wrong. describe() shows them immediately in the min and max rows.
Summary#
isna().sum()counts missing values;fillna/dropnafix them.drop_duplicates()removes repeated rows.pd.to_numeric(..., errors="coerce")turns text into numbers..strmethods clean a whole text column at once.
Quick quiz
3 questions. Check what stuck and earn 2 XP for each right answer.
Progress is saved in this browser. Create a free account to keep it on every device.
Get new lessons in your inbox
One email when we publish a new tutorial or guide. No spam, unsubscribe in one click.