Mathew K Analytics

Lesson 11 · Mastering Pandas

How to Identify and Handle Missing Data in Python Pandas for Accurate Data Analysis

Missing data is everywhere in the real world. It is important to know how to find, understand, and handle missing values so your analysis is reliable. In…

⬇ Download notebookOpen in Colab ↗

📓 Full notebook

Download .ipynb

Lesson: Identifying and Handling Missing Data in Pandas#

Missing data is everywhere in the real world.

It is important to know how to find, understand, and handle missing values so your analysis is reliable.

In this lesson, we will work with the Titanic dataset to see practical steps for dealing with missing data.

By the end, you will be able to spot missing values and choose appropriate ways to handle them.

Let us get started!

# Suppress all warnings to keep outputs clean
import warnings; warnings.filterwarnings("ignore")
import numpy as np
np.random.seed(42)
# Data setup (Titanic Dataset)
import pandas as pd
url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
df = pd.read_csv(url)
print(df.shape)
print(df.head(3))
(891, 12)
   PassengerId  Survived  Pclass  \
0            1         0       3   
1            2         1       1   
2            3         1       3   

                                                Name     Sex   Age  SibSp  \
0                            Braund, Mr. Owen Harris    male  22.0      1   
1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   
2                             Heikkinen, Miss. Laina  female  26.0      0   

   Parch            Ticket     Fare Cabin Embarked  
0      0         A/5 21171   7.2500   NaN        S  
1      0          PC 17599  71.2833   C85        C  
2      0  STON/O2. 3101282   7.9250   NaN        S  

Why Do We Care About Missing Data?#

Missing data can be caused by sensor errors, skipped survey questions, or lost files.

If we ignore missing values, our results might be incorrect or misleading.

Pandas gives us flexible tools to detect and handle missing data easily.

# Check for missing values in all columns
df.isnull().sum()
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
# Get the percentage of missing values per column
(df.isnull().sum() / len(df) * 100).round(2)
PassengerId     0.00
Survived        0.00
Pclass          0.00
Name            0.00
Sex             0.00
Age            19.87
SibSp           0.00
Parch           0.00
Ticket          0.00
Fare            0.00
Cabin          77.10
Embarked        0.22
dtype: float64
# See which rows are missing any data
df[df.isnull().any(axis=1)].head()
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S

Exploring Missing Data Visually#

It helps to see missing data with colors or charts.

Next, we will use a heatmap to quickly spot where values are missing in the Titanic dataset.

import seaborn as sns
import matplotlib.pyplot as plt
# Draw a heatmap of missing values
plt.figure(figsize=(10,4))
sns.heatmap(df.isnull(), cbar=False, yticklabels=False, cmap='viridis')
plt.title('Missing Data on Titanic')
plt.show()
No description has been provided for this image
# Count missing values in Cabin by passenger class
df.groupby('Pclass')['Cabin'].apply(lambda x: x.isnull().mean()).round(2)
Pclass
1    0.19
2    0.91
3    0.98
Name: Cabin, dtype: float64

Approaches for Handling Missing Data#

  • Drop: Remove rows or columns with missing data
  • Impute: Fill missing values using statistics or formulas
  • Leave As Is: Sometimes you can work with missingness directly

Let us see examples of each way.

# Drop rows where Age is missing
df_drop_age = df.dropna(subset=['Age'])
print('Original:', df.shape)
print('After dropping:', df_drop_age.shape)
Original: (891, 12)
After dropping: (714, 12)
# Fill missing Age values with the median age
median_age = df['Age'].median()
df['Age_filled'] = df['Age'].fillna(median_age)
print(f'Median Age: {median_age}')
print('Missing after fill:', df["Age_filled"].isnull().sum())
Median Age: 28.0
Missing after fill: 0
# Fill missing Embarked values with most common port
mode_embarked = df['Embarked'].mode()[0]
df['Embarked_filled'] = df['Embarked'].fillna(mode_embarked)
print(f'Most common port: {mode_embarked}')
print('Missing after fill:', df["Embarked_filled"].isnull().sum())
Most common port: S
Missing after fill: 0
# Mark missing Cabin values with a flag
df['Cabin_missing'] = df['Cabin'].isnull().astype(int)
df[['Cabin', 'Cabin_missing']].head(5)
Cabin Cabin_missing
0 NaN 1
1 C85 0
2 NaN 1
3 C123 0
4 NaN 1

Filling Technique: Forward and Backward Fill#

  • ffill (forward fill) copies the last known value down.
  • bfill (backward fill) uses the next value up.

These are often used in time series data.

# Demonstrate forward fill and backward fill on small Age sample
sample = df[['Age']].head(10).copy()
sample.loc[[2, 5], 'Age'] = None
sample['ffill'] = sample['Age'].ffill()
sample['bfill'] = sample['Age'].bfill()
print(sample)
    Age  ffill  bfill
0  22.0   22.0   22.0
1  38.0   38.0   38.0
2   NaN   38.0   35.0
3  35.0   35.0   35.0
4  35.0   35.0   35.0
5   NaN   35.0   54.0
6  54.0   54.0   54.0
7   2.0    2.0    2.0
8  27.0   27.0   27.0
9  14.0   14.0   14.0
# Impute missing Age by median per Passenger Class
df['Age_group_median'] = df.groupby('Pclass')['Age'].transform(lambda x: x.fillna(x.median()))
print(df[['Pclass', 'Age', 'Age_group_median']].head(8))
   Pclass   Age  Age_group_median
0       3  22.0              22.0
1       1  38.0              38.0
2       3  26.0              26.0
3       1  35.0              35.0
4       3  35.0              35.0
5       3   NaN              24.0
6       1  54.0              54.0
7       3   2.0               2.0
# Drop columns with over 70 percent missing values
thresh = 0.7 * len(df)
df_reduced = df.dropna(axis=1, thresh=thresh)
print(f'Columns dropped: {set(df.columns) - set(df_reduced.columns)}')
Columns dropped: {'Cabin'}
# Replace placeholder like '?' and 'NA' with true missing values
df2 = df.copy()
df2.replace(['?', 'NA', '-', ''], pd.NA, inplace=True)
print('Done recoding placeholders.')
Done recoding placeholders.

Mini-Project: Handling Missing Data for Analysis#

Let us prepare the Titanic data for survival study.

Apply the best fills for Age and Embarked. Drop columns that are mostly missing.

This helps make any future analysis trustworthy.

# Pipeline: fill Age by Pclass median, fill Embarked by mode, drop 'Cabin' and rows still missing
clean_df = df.copy()
clean_df['Age'] = clean_df.groupby('Pclass')['Age'].transform(lambda x: x.fillna(x.median()))
clean_df['Embarked'] = clean_df['Embarked'].fillna(clean_df['Embarked'].mode()[0])
clean_df = clean_df.drop(columns=['Cabin'])
clean_df = clean_df.dropna()
print(clean_df.isnull().sum().sum(), 'missing left')
print(clean_df.shape)
0 missing left
(891, 15)

Troubleshooting Tips for Missing Data#

  • Watch out for nonstandard missing codes, like 999 or N/A.
  • Visualize missingness early with plots.
  • Try multiple fill methods; check which gives better analysis.

Always check for missing data before any modeling.

# Challenge: Identify if a record is missing more than one field
df['missing_count'] = df.isnull().sum(axis=1)
challenge_result = df[df['missing_count'] > 1]
print(challenge_result.shape)
(158, 17)

Lesson Recap#

  • We detected missing values by count and percentage.
  • We visualized missing spots with a heatmap.
  • We dropped, filled, or flagged missing data.
  • We explored thoughtful strategies for real projects.

Handling missing data is vital for any serious pandas work.

Thanks for Learning with Us!#

Try these missing value techniques on your own data next.

If you enjoyed this video, subscribe to our channel and leave your favorite pandas tip in the comments.

Happy analyzing!

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.