Python Central HubSign in

Data Analytics with Python / Phase 3: Data Manipulation with Pandas

Cleaning Data (astype, duplicates, string cleaning)

Clean messy real-world data - fix types, remove duplicates, and normalize text values.

What "dirty data" looks like

Common problems:

  • Numbers stored as strings ("1,200", " 42 ")
  • Inconsistent categories ("Delhi", "delhi", " DELHI ")
  • Duplicate rows
  • Weird whitespace and punctuation

Example dataset

Python
import pandas as pd
 
df = pd.DataFrame({
    "name": [" Asha ", "Ravi", "ravi", "Meera"],
    "city": ["delhi", "Delhi ", "DELHI", " Pune"],
    "amount": ["1,200", "500", "500", " 700 "],
})
 
print(df)

1) Fix text: str.strip, str.lower, str.replace

Python
clean = df.copy()
clean["name"] = clean["name"].str.strip()
clean["city"] = clean["city"].str.strip().str.lower()
print(clean)

2) Convert string numbers to numeric: to_numeric

Remove commas and spaces first

Python
clean = df.copy()
clean["amount"] = clean["amount"].astype(str).str.replace(",", "", regex=False).str.strip()
clean["amount"] = pd.to_numeric(clean["amount"], errors="coerce")
 
print(clean)
print(clean.dtypes)

errors="coerce" turns invalid values into NaN (so you can handle them with dropna/fillna).

3) Change column types safely: astype

Python
clean = clean.astype({"amount": "int64"})
print(clean.dtypes)

If conversion fails, Pandas throws an error. Prefer to_numeric(..., errors="coerce") for messy data.

4) Remove duplicates: drop_duplicates

Exact duplicates

Python
dedup = clean.drop_duplicates()
print(dedup)

Duplicates based on a subset of columns

Python
dedup = clean.drop_duplicates(subset=["name", "city"], keep="first")
print(dedup)

Tip: validate your cleaning

After cleaning, quickly check:

  • df.dtypes
  • df.isna().sum()
  • df["col"].value_counts() for categories

Cleaning is not a single step. It's a loop: inspect → clean → validate.

Visualize it

diagram The cleaning loop mermaid
Cleaning data is iterative: inspect, clean, validate, and repeat until the data is trustworthy.

🧪 Try It Yourself

Exercise 1 – Strip Whitespace From Text

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 2 – Convert Text Numbers Safely

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 3 – Drop Duplicate Rows

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Check your understanding

quizCheck yourself
  1. What does pd.to_numeric(col, errors="coerce") do with a value that cannot be parsed as a number?

    Show answer

    B — Turns it into NaN — errors=coerce converts invalid values to NaN so you can handle them with dropna or fillna. astype, by contrast, raises an error.

  2. To convert the amount strings "1,200" and " 700 " to numbers, what must you do before to_numeric?

    Show answer

    A — Remove the commas and strip the spaces — The lesson chains str.replace(",", "", regex=False) and str.strip() first, then calls to_numeric.

  3. Which call removes rows that repeat the same name and city, keeping the first one?

    Show answer

    A — df.drop_duplicates(subset=["name", "city"], keep="first") — drop_duplicates with subset compares only those columns. duplicated().sum() just counts exact duplicate rows.

  4. Why does the lesson normalize city values with str.strip().str.lower() before comparing?

    Show answer

    A — Delhi, delhi and DELHI would otherwise count as different categories — Inconsistent case and stray whitespace create fake categories and hide duplicates.

Next

Text cleanup is worth its own deep dive — continue to Text and String Methods (str accessor and regex) to handle messier text patterns with the .str accessor and regex.

Was this page helpful?

Let us know how we did