Data Cleaning
Learn how to transform messy, incomplete and inconsistent datasets into reliable data ready for analysis. This lesson covers missing values, duplicate records, incorrect data types, text cleaning, dates, outliers, validation and professional data-cleaning workflows using Pandas.
Learning Objectives
Data cleaning is one of the most important practical skills for a data analyst. Real-world datasets often contain missing, duplicated, incorrectly formatted or inconsistent information.
You will learn how to:
- Understand what data cleaning means.
- Inspect an unfamiliar dataset.
- Identify missing values.
- Remove or replace missing data.
- Detect and remove duplicates.
- Correct incorrect data types.
- Clean inconsistent text values.
- Standardize column values.
- Convert dates correctly.
- Clean numeric values.
- Identify potential outliers.
- Validate business rules.
- Rename columns professionally.
- Use conditional transformations.
- Use
apply()when appropriate. - Build a repeatable cleaning workflow.
What Is Data Cleaning?
Data cleaning is the process of detecting and correcting inaccurate, incomplete, duplicated, inconsistent or improperly formatted data.
Consider the following customer dataset:
Name Age City
Ali 25 Lahore
ali 25 lahore
Sara NaN Islamabad
Ahmed "31" ISB
The data contains several problems:
- Different capitalization.
- A duplicated customer.
- A missing age.
- Age stored as text.
- Different representations of Islamabad.
Clean Data
The goal is not simply to make a dataset look better. The goal is to make the data accurate, consistent and suitable for the intended analysis.
Why Data Cleaning Matters
Poor-quality data can produce poor-quality analysis.
Bad Data
↓
Incorrect Calculations
↓
Incorrect Analysis
↓
Incorrect Decisions
For example, if a sales dataset contains duplicate transactions, the calculated revenue may be higher than the actual revenue.
Important Principle
Never blindly modify data. First understand what the data represents and why an unusual value exists.
Professional Data Cleaning Workflow
A professional cleaning process usually follows a structured workflow.
1. Load Data
↓
2. Inspect Data
↓
3. Identify Problems
↓
4. Clean Data
↓
5. Validate Data
↓
6. Analyze Data
↓
7. Export Clean Dataset
Think Before You Clean
Data cleaning is not just a collection of Pandas commands. It is a reasoning process. You must understand what each column represents before deciding how to modify it.
Inspecting Data
Before changing anything, inspect the dataset.
import pandas as pd
df = pd.read_csv(
"sales.csv"
)
print(df.head())
print(df.shape)
print(df.columns)
print(df.info())
print(df.describe())
You should investigate:
- Number of rows.
- Number of columns.
- Column names.
- Data types.
- Missing values.
- Unexpected values.
- Duplicate records.
Finding Missing Values
Missing values are extremely common in real-world datasets.
print(df.isna())
To count missing values in each column:
print(
df.isna().sum()
)
To calculate the percentage of missing values:
missing_percentage = (
df.isna().mean() * 100
)
print(missing_percentage)
Why Percentage Matters
Knowing that a column has 100 missing values is useful, but knowing that those 100 values represent 1% or 80% of the dataset provides much more context.
Removing Missing Data
Pandas provides dropna() for removing
rows or columns containing missing values.
cleaned = df.dropna()
print(cleaned)
You can remove rows only when specific columns are missing.
cleaned = df.dropna(
subset=["CustomerID"]
)
You can also remove columns containing missing values, although this should be done carefully.
cleaned = df.dropna(
axis=1
)
Do Not Delete Automatically
Removing missing rows may also remove valuable information. Always determine why values are missing before deleting them.
Filling Missing Values
Instead of deleting missing values, you can replace them with appropriate values.
df["Age"] = df[
"Age"
].fillna(0)
For numerical data, the mean or median may sometimes be useful.
median_age = df[
"Age"
].median()
df["Age"] = df[
"Age"
].fillna(median_age)
For categorical data, a common strategy is to use the
most frequent value or an explicit category such as
"Unknown".
df["City"] = df[
"City"
].fillna("Unknown")
Choose Based on Context
There is no universal replacement value for every missing field. The correct approach depends on the meaning and distribution of the data.
Detecting Duplicate Records
Duplicate rows can lead to incorrect calculations.
duplicates = df.duplicated()
print(duplicates)
Count duplicates:
print(
df.duplicated().sum()
)
Remove complete duplicate rows:
df = df.drop_duplicates()
You can also identify duplicates based on specific columns.
df.duplicated(
subset=["CustomerID"]
)
Correcting Data Types
A dataset may contain numbers stored as strings, dates stored as text or inconsistent types.
print(df.dtypes)
Convert a column to numeric data:
df["Price"] = pd.to_numeric(
df["Price"],
errors="coerce"
)
With errors="coerce", values that cannot
be converted become missing values.
df["Quantity"] = df[
"Quantity"
].astype("Int64")
Check Before Converting
Always inspect unusual values before converting
them. A value such as "1,200" may
require additional cleaning before numeric
conversion.
Cleaning Text Data
Text fields frequently contain extra spaces, inconsistent capitalization and formatting problems.
df["Name"] = df[
"Name"
].str.strip()
Convert text to lowercase:
df["City"] = df[
"City"
].str.lower()
Convert text to uppercase:
df["Code"] = df[
"Code"
].str.upper()
Capitalize words:
df["City"] = df[
"City"
].str.title()
Example
" Lahore "
"LAHORE"
"lahore"
"Lahore "
These values may represent the same city but are not textually identical.
Replacing Values
Use replace() when values need to be
standardized.
df["City"] = df[
"City"
].replace({
"ISB": "Islamabad",
"LHR": "Lahore"
})
You can also replace individual values:
df["Status"] = df[
"Status"
].replace(
"Completed ",
"Completed"
)
Combining replacement with string cleaning can create a more reliable standardization process.
Cleaning Dates
Dates are often imported as strings and need to be converted before analysis.
df["OrderDate"] = pd.to_datetime(
df["OrderDate"],
errors="coerce"
)
Once converted, you can extract useful components.
df["Year"] = (
df["OrderDate"].dt.year
)
df["Month"] = (
df["OrderDate"].dt.month
)
df["Day"] = (
df["OrderDate"].dt.day
)
Why Dates Matter
Correctly formatted dates allow you to perform time-based analysis such as monthly sales, yearly revenue and daily trends.
Cleaning Numeric Data
Numeric fields can contain currency symbols, commas, spaces or other characters.
prices = pd.Series([
"$1,200",
"$850",
"$2,500"
])
prices = (
prices
.str.replace("$", "", regex=False)
.str.replace(",", "", regex=False)
.astype(float)
)
print(prices)
Output
0 1200.0
1 850.0
2 2500.0
dtype: float64
Numeric cleaning is particularly important when data comes from manually maintained spreadsheets or exported reports.
Understanding Outliers
An outlier is a value that is unusually different from other observations.
sales = pd.Series([
100,
120,
110,
105,
115,
5000
])
print(
sales.describe()
)
The value 5000 is dramatically larger than
the other values.
Outlier Does Not Automatically Mean Error
A large value could be a data-entry mistake, but it could also represent a legitimate large transaction. Investigate before removing it.
Simple Statistical Approach
One common technique uses the interquartile range (IQR).
q1 = sales.quantile(0.25)
q3 = sales.quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
outliers = sales[
(sales < lower) |
(sales > upper)
]
print(outliers)
This is a useful analytical technique, but the appropriate outlier method depends on the dataset and business problem.
Data Validation
Cleaning should be followed by validation.
Suppose product quantity must always be greater than zero.
invalid = df[
df["Quantity"] <= 0
]
print(invalid)
Validate prices:
invalid_prices = df[
df["Price"] < 0
]
Validate categories:
valid_categories = [
"Electronics",
"Clothing",
"Home"
]
invalid = df[
~df["Category"].isin(
valid_categories
)
]
Cleaning + Validation
Cleaning changes problematic data. Validation checks whether the resulting dataset satisfies the rules required for analysis.
Cleaning Column Names
Consistent column names make analytical code easier to understand and maintain.
df.columns = (
df.columns
.str.strip()
.str.lower()
.str.replace(" ", "_")
)
print(df.columns)
For example:
Customer Name
Order Date
Total Sales
can become:
customer_name
order_date
total_sales
Professional Convention
Snake case such as
customer_name and
order_date is a common and readable
convention for Python-oriented data workflows.
Standardizing Data
Standardization means representing equivalent values consistently.
df["Gender"] = df[
"Gender"
].replace({
"M": "Male",
"m": "Male",
"F": "Female",
"f": "Female"
})
Another example:
df["Payment"] = df[
"Payment"
].str.strip().str.title()
This can turn values such as:
" cash "
"Cash"
"cash"
"CASH"
into a consistent representation.
Conditional Cleaning
Sometimes the correct cleaning rule depends on a condition.
df.loc[
df["Age"] < 0,
"Age"
] = None
You can also create standardized categories.
df["CustomerType"] = "Regular"
df.loc[
df["TotalSales"] >= 5000,
"CustomerType"
] = "Premium"
This approach is useful when business rules are known and clearly defined.
Using apply()
apply() allows you to apply a function to
values in a Series or along a DataFrame axis.
def clean_name(name):
return name.strip().title()
df["Name"] = df[
"Name"
].apply(clean_name)
For simple operations, built-in vectorized Pandas methods are often preferable because they are generally clearer and can be more efficient.
df["Name"] = df[
"Name"
].str.strip().str.title()
Good Practice
Use apply() when you genuinely need
custom row-by-row or value-by-value logic. Do not
automatically use it for operations that Pandas
already provides directly.
Keep the Raw Data Safe
A professional data workflow should preserve the original dataset.
raw_df = pd.read_csv(
"sales.csv"
)
df = raw_df.copy()
Perform cleaning on df while keeping
raw_df unchanged.
df["Name"] = (
df["Name"]
.str.strip()
.str.title()
)
Professional Principle
Keep a clear separation between raw data, cleaned data and analytical outputs whenever practical. This makes the workflow easier to audit and repeat.
Practical Example — Cleaning Ecommerce Data
Consider this intentionally messy ecommerce dataset.
import pandas as pd
df = pd.DataFrame({
"Customer Name": [
" ali ",
"Sara",
"Ahmed",
"Ali"
],
"City": [
"lahore",
"ISB",
" Islamabad ",
"Lahore"
],
"Price": [
"$1,200",
"$800",
"$500",
"$1,200"
],
"Quantity": [
"2",
"3",
"1",
"2"
]
})
print(df)
Step 1 — Clean Column Names
df.columns = (
df.columns
.str.strip()
.str.lower()
.str.replace(" ", "_")
)
Step 2 — Clean Customer Names
df["customer_name"] = (
df["customer_name"]
.str.strip()
.str.title()
)
Step 3 — Standardize Cities
df["city"] = (
df["city"]
.str.strip()
.str.title()
)
df["city"] = df[
"city"
].replace({
"Isb": "Islamabad"
})
Step 4 — Clean Prices
df["price"] = (
df["price"]
.str.replace("$", "", regex=False)
.str.replace(",", "", regex=False)
.astype(float)
)
Step 5 — Convert Quantity
df["quantity"] = pd.to_numeric(
df["quantity"],
errors="coerce"
)
Step 6 — Calculate Revenue
df["revenue"] = (
df["price"] *
df["quantity"]
)
Step 7 — Validate
print(df.info())
print(df.isna().sum())
print(df.duplicated().sum())
Final Workflow
Raw Ecommerce Data
↓
Column Cleaning
↓
Text Standardization
↓
Numeric Conversion
↓
Validation
↓
Calculated Revenue
↓
Analysis Ready
Common Data Cleaning Mistakes
Mistake 1 — Deleting Missing Rows Immediately
Missing values may contain important information. Investigate first.
Mistake 2 — Removing Every Outlier
An unusual value may be a legitimate transaction. Do not assume that unusual means incorrect.
Mistake 3 — Modifying the Original Dataset
Always consider preserving a raw copy so your cleaning decisions can be reviewed later.
Mistake 4 — Ignoring Data Types
A number stored as text can cause incorrect calculations or prevent analytical operations.
Mistake 5 — Cleaning Without Understanding the Data
A technically correct Pandas operation can still produce a logically incorrect dataset if the business meaning is misunderstood.
Practice Exercises
Exercise 1 — Missing Values
Create a DataFrame containing missing ages and salaries. Detect the missing values and calculate their percentages.
Exercise 2 — Duplicate Records
Create duplicate customer records. Detect and remove the duplicates.
Exercise 3 — Clean Text
Clean a column containing values such as
" lahore ",
"LAHORE" and
"Lahore".
Exercise 4 — Currency
Convert values such as
"$1,500" into numerical values.
Exercise 5 — Dates
Convert an order-date column into a proper datetime column and extract the month and year.
Exercise 6 — Validation
Find all records where price or quantity is less than zero.
Mini Challenge — Real-World Sales Data Cleaner
Your company has received a messy sales report. Before the data can be analyzed, you must clean it.
Your Mission
- Clean the column names.
- Remove leading and trailing spaces.
- Standardize customer names.
- Standardize city names.
- Convert prices to numbers.
- Convert quantities to numbers.
- Detect missing values.
- Detect duplicate records.
- Remove genuine duplicates.
- Validate that prices are not negative.
- Validate that quantities are greater than zero.
- Create a revenue column.
- Save the cleaned dataset as a CSV file.
Starter Dataset
import pandas as pd
sales = pd.DataFrame({
" Customer Name ": [
" ali ",
"Sara",
"AHMED",
"Ali"
],
" City ": [
"lahore",
"ISB",
" Islamabad ",
"Lahore"
],
" Price ": [
"$1,200",
"$800",
"$500",
"$1,200"
],
" Quantity ": [
"2",
"3",
"1",
"2"
]
})
print(sales)
Suggested Cleaning Pipeline
# Preserve raw data
raw_sales = sales.copy()
# Clean column names
sales.columns = (
sales.columns
.str.strip()
.str.lower()
.str.replace(" ", "_")
)
# Clean names
sales["customer_name"] = (
sales["customer_name"]
.str.strip()
.str.title()
)
# Clean cities
sales["city"] = (
sales["city"]
.str.strip()
.str.title()
)
sales["city"] = sales[
"city"
].replace({
"Isb": "Islamabad"
})
# Clean prices
sales["price"] = (
sales["price"]
.str.replace("$", "", regex=False)
.str.replace(",", "", regex=False)
)
sales["price"] = pd.to_numeric(
sales["price"],
errors="coerce"
)
# Convert quantity
sales["quantity"] = pd.to_numeric(
sales["quantity"],
errors="coerce"
)
# Calculate revenue
sales["revenue"] = (
sales["price"] *
sales["quantity"]
)
print(sales)
Professional Extension
Add validation rules and create a final cleaned file.
invalid = sales[
(sales["price"] < 0) |
(sales["quantity"] <= 0)
]
print("Invalid records:")
print(invalid)
sales.to_csv(
"clean_sales.csv",
index=False
)
Think of this final CSV as the dataset you would hand to a data analyst or load into a BI tool.
Knowledge Check
1. What is data cleaning?
2. Which method detects missing values?
3. Which method removes duplicate rows?
4. What is fillna() used for?
5. What does pd.to_numeric() help with?
6. Why might str.strip() be useful?
7. What is an outlier?
8. Should every outlier be deleted?
9. Why preserve a raw dataset?
10. What should follow data cleaning?
Lesson Summary
Data cleaning is a critical part of professional data analysis. Before generating charts, calculating KPIs or building dashboards, analysts need confidence that the underlying data is reliable.
What You Learned
- Data cleaning prepares raw data for reliable analysis.
- Always inspect data before modifying it.
-
Missing values can be detected using
isna(). -
dropna()can remove missing records. -
fillna()can replace missing values. - Duplicate records can be detected and removed.
- Data types should be appropriate for the intended analysis.
- Text values often require trimming and standardization.
- Dates should be converted into proper datetime values.
- Currency and numeric fields may require additional cleaning.
- Outliers should be investigated rather than automatically deleted.
- Business rules can be used to validate data.
- Consistent column names improve maintainability.
-
apply()can handle custom transformations when appropriate. - Raw data should generally be preserved.
- Cleaning should be followed by validation.
You have now covered a complete foundation for preparing real-world datasets with Python and Pandas. The next lesson moves into Matplotlib, where you will turn cleaned data into meaningful visualizations and charts.
Ready to Continue?
You have completed the Data Cleaning lesson.