pandas
DataFrame
nan values
average
data cleaning

pandas DataFrame replace nan values with average of columns

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Replacing NaN values with the average of each column is one of the simplest forms of imputation in pandas. It is easy to implement and often useful for numeric preprocessing, but it also changes the distribution of the data, so it should be used intentionally rather than automatically.

The basic pandas solution

For a numeric DataFrame, the most direct pattern is:

python
1import pandas as pd
2import numpy as np
3
4df = pd.DataFrame({
5    "A": [1.0, 2.0, np.nan, 4.0],
6    "B": [np.nan, 5.0, np.nan, 7.0],
7    "C": [10.0, 11.0, 12.0, 13.0],
8})
9
10filled = df.fillna(df.mean(numeric_only=True))
11print(filled)

This works because:

  • 'df.mean(...) computes one mean per numeric column'
  • 'fillna(...) aligns those means by column name'
  • each NaN is replaced with the corresponding column mean

That makes the operation concise and fully vectorized.

What the result looks like

For the DataFrame above:

  • column A mean is (1 + 2 + 4) / 3
  • column B mean is (5 + 7) / 2
  • column C has no missing values

So the filled result becomes:

text
1          A    B     C
20  1.000000  6.0  10.0
31  2.000000  5.0  11.0
42  2.333333  6.0  12.0
53  4.000000  7.0  13.0

This is usually the quickest way to handle missing numeric values when a simple average-based imputation is acceptable.

Fill selected columns only

Sometimes you do not want to apply mean imputation to every numeric column. In that case, target the columns explicitly:

python
numeric_cols = ["A", "B"]
df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean())

This is useful when:

  • some numeric columns should stay missing
  • some columns represent IDs or codes rather than measured values
  • you want different imputation strategies for different features

Being explicit often makes the cleaning step safer and easier to review.

Handle non-numeric columns carefully

Mean imputation makes sense only for numeric data. If your DataFrame also contains strings or categories, keep them separate:

python
1df = pd.DataFrame({
2    "age": [20, None, 40],
3    "city": ["Toronto", "Montreal", None],
4})
5
6df["age"] = df["age"].fillna(df["age"].mean())
7df["city"] = df["city"].fillna("Unknown")

Trying to treat all columns the same way is a common source of messy preprocessing code.

Train-test leakage warning

If you are doing machine learning, compute the column means on the training set only, then apply those same values to validation or test data.

For example:

python
train_means = train_df.mean(numeric_only=True)
train_df = train_df.fillna(train_means)
test_df = test_df.fillna(train_means)

If you compute the means separately on the test set, you leak information from the test distribution into preprocessing. That makes evaluation less trustworthy.

This is one reason scikit-learn pipelines and imputers are often preferable in production ML workflows.

Know when mean imputation is too naive

Replacing missing values with the mean is simple, but it has drawbacks:

  • it reduces variance
  • it can blur real patterns
  • it is sensitive to outliers
  • it may be a poor fit for skewed distributions

For some columns, median imputation or model-based imputation is more appropriate. The point is not that mean imputation is bad. The point is that it is a baseline, not a universal best practice.

Common Pitfalls

The biggest mistake is applying mean imputation to columns where an average has no meaningful interpretation, such as category codes or identifiers.

Another common issue is forgetting that the mean should usually come from the training data only in machine learning workflows.

People also use mean imputation on heavily skewed or outlier-dominated columns where the median would be much more stable.

Finally, if an entire column is missing, its mean may also be NaN, so fillna(df.mean()) will not magically repair that case.

Summary

  • Use df.fillna(df.mean(numeric_only=True)) for simple column-wise mean imputation.
  • Target only the columns where average-based filling actually makes sense.
  • Treat non-numeric columns with a different strategy.
  • In ML workflows, compute the imputation values on the training set and reuse them for test data.
  • Remember that mean imputation is simple and convenient, but not always statistically ideal.

Course illustration
Course illustration

All Rights Reserved.