pandas
Python
DataFrame
NaN
data analysis

How do I count the NaN values in a column in pandas DataFrame?

Master System Design with Codemia

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

Introduction

To count NaN values in a pandas DataFrame column, use df['column'].isna().sum(). This returns the number of missing values in that column. For the entire DataFrame, use df.isna().sum() to get NaN counts per column, or df.isna().sum().sum() for the total count across all columns. The isna() method (alias isnull()) creates a boolean mask where True indicates a NaN value, and sum() counts the True values.

Count NaN in a Single Column

python
1import pandas as pd
2import numpy as np
3
4df = pd.DataFrame({
5    'name': ['Alice', 'Bob', None, 'Diana', 'Eve'],
6    'age': [25, np.nan, 30, np.nan, 28],
7    'salary': [50000, 60000, np.nan, 55000, np.nan]
8})
9
10# Count NaN in one column
11nan_count = df['age'].isna().sum()
12print(nan_count)  # 2
13
14# Alternative: isnull() is an alias for isna()
15nan_count = df['age'].isnull().sum()
16print(nan_count)  # 2

Count NaN Per Column

python
1# NaN count for every column
2print(df.isna().sum())
3# name      1
4# age       2
5# salary    2
6# dtype: int64
7
8# Only columns with NaN values
9nan_counts = df.isna().sum()
10print(nan_counts[nan_counts > 0])
11# name      1
12# age       2
13# salary    2
14# dtype: int64

Count NaN for the Entire DataFrame

python
1# Total NaN across all columns
2total_nan = df.isna().sum().sum()
3print(total_nan)  # 5
4
5# Alternative: count all values, then count non-NaN
6total_nan = df.size - df.count().sum()
7print(total_nan)  # 5

NaN Percentage

python
1# Percentage of NaN per column
2nan_pct = df.isna().mean() * 100
3print(nan_pct)
4# name      20.0
5# age       40.0
6# salary    40.0
7# dtype: float64
8
9# Formatted output
10for col in df.columns:
11    pct = df[col].isna().mean() * 100
12    count = df[col].isna().sum()
13    print(f"{col}: {count} NaN ({pct:.1f}%)")
14# name: 1 NaN (20.0%)
15# age: 2 NaN (40.0%)
16# salary: 2 NaN (40.0%)

Count Non-NaN Values

python
1# count() returns non-NaN values per column
2print(df.count())
3# name      4
4# age       3
5# salary    3
6# dtype: int64
7
8# For a single column
9non_nan = df['age'].count()
10print(non_nan)  # 3
11
12# Equivalently
13non_nan = df['age'].notna().sum()
14print(non_nan)  # 3

NaN Count Per Row

python
1# How many NaN values in each row
2print(df.isna().sum(axis=1))
3# 0    0
4# 1    1
5# 2    2
6# 3    1
7# 4    1
8# dtype: int64
9
10# Rows with any NaN
11rows_with_nan = df[df.isna().any(axis=1)]
12print(len(rows_with_nan))  # 4 rows have at least one NaN

Using info() for a Quick Overview

python
1df.info()
2# <class 'pandas.core.frame.DataFrame'>
3# RangeIndex: 5 entries, 0 to 4
4# Data columns (total 3 columns):
5#  #   Column  Non-Null Count  Dtype
6# ---  ------  --------------  -----
7#  0   name    4 non-null      object
8#  1   age     3 non-null      float64
9#  2   salary  3 non-null      float64
10# dtypes: float64(2), object(1)
11
12# Non-Null Count shows how many values are NOT NaN
13# 5 total - 3 non-null = 2 NaN for 'age'

Using describe() for NaN Awareness

python
1print(df.describe())
2#             age        salary
3# count  3.000000      3.000000
4# mean  27.666667  55000.000000
5# ...
6
7# The 'count' row shows non-NaN values
8# 'age' has count=3 out of 5 rows → 2 NaN

Counting Specific Missing Value Types

python
1# NaN is not the only "missing" value
2df2 = pd.DataFrame({
3    'col': [1, np.nan, None, '', 0, pd.NaT, 'N/A']
4})
5
6# isna() catches NaN, None, and NaT
7print(df2['col'].isna().sum())  # 3 (NaN, None, NaT)
8
9# Empty strings and 'N/A' are NOT considered NaN
10# Count those separately
11empty_count = (df2['col'] == '').sum()
12na_string_count = (df2['col'] == 'N/A').sum()
13
14# Replace custom missing indicators, then count
15df2['col'] = df2['col'].replace({'': np.nan, 'N/A': np.nan, 0: np.nan})
16print(df2['col'].isna().sum())  # 6

Common Pitfalls

  • Confusing count() with len(): df['col'].count() returns the number of non-NaN values. len(df['col']) returns the total number of rows including NaN. To get NaN count: len(df['col']) - df['col'].count() or simply df['col'].isna().sum().
  • Empty strings are not NaN: isna() detects np.nan, None, and pd.NaT but NOT empty strings (''), zeros (0), or placeholder text ('N/A', 'null'). Use df['col'].replace('', np.nan) before counting if empty strings represent missing data in your dataset.
  • NaN comparisons with ==: np.nan == np.nan is False in Python. Never use df['col'] == np.nan to find missing values — it returns all False. Always use df['col'].isna() or pd.isna(df['col']).
  • Using sum() without isna() first: df['col'].sum() adds up the numeric values (skipping NaN). It does not count NaN. You need df['col'].isna().sum() — first create the boolean mask, then sum it.
  • Integer columns silently converting to float: When a column with integer data has NaN values, pandas converts the entire column to float64 because standard int does not support NaN. Use pd.Int64Dtype() (nullable integer) to keep integer type: df['col'] = df['col'].astype('Int64').

Summary

  • Use df['col'].isna().sum() to count NaN in a single column
  • Use df.isna().sum() for NaN counts per column, df.isna().sum().sum() for total
  • Use df.isna().mean() * 100 for NaN percentage per column
  • Use df.isna().sum(axis=1) to count NaN per row
  • isna() and isnull() are identical — use either one consistently

Course illustration
Course illustration

All Rights Reserved.