Pandas Cleaning Empty Cells

Empty cells are the most common data quality problem, and pandas gives you two straightforward tools to deal with them: dropna() to remove them and fillna() to replace them.

Finding Empty Cells

Before you can fix empty cells, you need to know exactly where they are. pandas represents missing values as NaN (Not a Number), and isnull() returns a same-shaped DataFrame of True/False values marking every empty cell. Chaining .sum() on top counts how many empty cells are in each column.

Example

import pandas as pd
import numpy as np

data = {
    'Customer': ['Ann', 'Ben', 'Cleo', 'Dev', 'Faye'],
    'Amount': [250.0, np.nan, 175.5, np.nan, 410.0],
    'Country': ['USA', 'Canada', 'USA', None, 'USA']
}
df = pd.DataFrame(data)

print(df.isnull().sum())
# Customer    0
# Amount      2
# Country     1
# dtype: int64

Removing Rows with dropna()

dropna() removes any row that contains at least one empty cell. This is the simplest option when missing rows are rare and you can afford to lose them, but it can throw away good data in other columns if even one field is missing.

Example

import pandas as pd
import numpy as np

data = {
    'Customer': ['Ann', 'Ben', 'Cleo', 'Dev', 'Faye'],
    'Amount': [250.0, np.nan, 175.5, np.nan, 410.0],
    'Country': ['USA', 'Canada', 'USA', None, 'USA']
}
df = pd.DataFrame(data)

df_no_empty = df.dropna()
print(df_no_empty)

# Drop only rows missing a specific column
df_no_missing_amount = df.dropna(subset=['Amount'])
print(df_no_missing_amount)
Note: dropna() returns a new DataFrame by default and leaves the original untouched. To modify df directly, either reassign it (df = df.dropna()) or pass inplace=True: df.dropna(inplace=True).

Filling Empty Cells with fillna()

Instead of losing rows, fillna() lets you replace empty cells with a value of your choice. You can fill an entire DataFrame with one value, or target a single column — which is usually the safer approach, since a sensible fill value for Amount is rarely sensible for Country.

Example

import pandas as pd
import numpy as np

data = {
    'Customer': ['Ann', 'Ben', 'Cleo', 'Dev', 'Faye'],
    'Amount': [250.0, np.nan, 175.5, np.nan, 410.0],
    'Country': ['USA', 'Canada', 'USA', None, 'USA']
}
df = pd.DataFrame(data)

mean_amount = df['Amount'].mean()
df['Amount'] = df['Amount'].fillna(mean_amount)
df['Country'] = df['Country'].fillna('Unknown')
print(df)
  • Fill with a fixed value for a clear default, e.g. fillna('Unknown')
  • Fill numeric columns with mean(), median(), or mode() to preserve the overall distribution
  • Fill time-ordered data with method='ffill' (carry the last known value forward) or method='bfill'
  • Leave a column unfilled and dropna() it instead when there is no reasonable default
MethodEffectBest when
dropna()Removes rows with any empty cellMissing rows are rare and safe to discard
fillna(value)Replaces empty cells with a chosen valueYou have a sensible default or statistic to substitute
Note: Use df['Amount'].mean() rather than a hardcoded number when filling numeric columns — it adapts automatically if the underlying data changes, and it keeps the column's average roughly unchanged.