Skip to main content

Python Server: What Is the Difference Between isna() and isnull() in Pandas

When working with missing data in Pandas, you will quickly encounter two methods that appear to do the same thing: .isna() and .isnull(). This naturally raises the question of whether they behave differently and which one you should use in your code.

This guide gives you a definitive answer, explains the historical reasons behind having two names, and shows practical patterns for working with missing values effectively.

They Are Identical

In Pandas, .isna() and .isnull() are exact aliases. They point to the same underlying function and produce identical results in every situation. There is no difference in behavior, performance, or edge-case handling:

import pandas as pd
import numpy as np

df = pd.DataFrame({'A': [1, np.nan, 3, None]})

# Confirm they produce identical results
print(df['A'].isna().equals(df['A'].isnull()))

Output:

True

This is not a coincidence or an approximation. Internally, one is literally defined as an alias for the other in the Pandas source code.

Why Do Two Names Exist?

Pandas provides both methods to accommodate users coming from different programming backgrounds:

MethodConventionBackground
.isna()Python / NumPyMirrors np.isnan() and the pd.NA naming
.isnull()R languageMirrors R's is.null() function

Early versions of Pandas leaned toward the R-style .isnull() naming. The .isna() variant was introduced later to align more closely with Python and NumPy conventions. Both were kept to avoid breaking existing code.

What Values Do They Detect?

Both methods detect the same set of missing value types in Pandas. This includes np.nan, Python's None, and the newer pd.NA used with Pandas nullable types:

import pandas as pd
import numpy as np

s = pd.Series([1, np.nan, None, pd.NA, 'text'])

print(s.isna())

Output:

0    False
1 True
2 True
3 True
4 False
dtype: bool

The detected missing values are:

  • np.nan: the standard NumPy floating-point "not a number" sentinel
  • None: Python's built-in null object
  • pd.NA: the Pandas nullable scalar introduced for nullable integer, boolean, and string types

Regular values like integers, floats, and strings are never considered missing, regardless of which method you use.

Common Usage Patterns

Beyond simply checking which values are missing, .isna() is frequently combined with aggregation and filtering methods to summarize or handle missing data across a DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({
'A': [1, np.nan, 3],
'B': [np.nan, 2, 3]
})

# Count missing values per column
print("Missing per column:")
print(df.isna().sum())

# Check if any missing values exist anywhere
print("\nAny missing at all:", df.isna().any().any())

# Total missing count across entire DataFrame
print("Total missing:", df.isna().sum().sum())

# Filter rows that contain at least one missing value
print("\nRows with missing values:")
print(df[df.isna().any(axis=1)])

Output:

Missing per column:
A 1
B 1
dtype: int64

Any missing at all: True
Total missing: 2

Rows with missing values:
A B
0 1.0 NaN
1 NaN 2.0
tip

Chaining .isna().sum() is the fastest way to get a per-column missing value count. For a percentage, divide by len(df) and multiply by 100.

Complementary Methods: notna() and notnull()

Just as .isna() and .isnull() are aliases, their complements .notna() and .notnull() are also identical to each other. They return True for every value that is not missing:

CheckMethods (identical)
Value is missing.isna() / .isnull()
Value is present.notna() / .notnull()
import pandas as pd
import numpy as np

s = pd.Series([1, np.nan, 3])

print("notna():")
print(s.notna())

print("\nnotnull():")
print(s.notnull())

Output:

notna():
0 True
1 False
2 True
dtype: bool

notnull():
0 True
1 False
2 True
dtype: bool

These are useful for filtering rows where a specific column has valid data:

import pandas as pd
import numpy as np

df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'score': [85, np.nan, 92]
})

# Keep only rows where score is present
valid = df[df['score'].notna()]
print(valid)

Output:

      name  score
0 Alice 85.0
2 Charlie 92.0

Which One Should You Use?

The recommended choice is isna() and notna() for the following reasons:

  • Python/NumPy alignment: They match the np.isnan() and pd.NA naming conventions used elsewhere in the ecosystem.
  • Modern documentation: The official Pandas documentation predominantly uses isna() in its examples.
  • Semantic clarity: "NA" (not available) is a more precise description of what these methods check for than "null," which has a different meaning in many programming contexts.
# Preferred style
df.isna().sum()
df.notna().all()

# Works identically, but less conventional in modern Pandas code
df.isnull().sum()
df.notnull().all()
info

Neither method is deprecated, and there are no plans to remove .isnull() or .notnull(). However, consistency within your codebase matters. Pick one style and use it everywhere.

Quick Reference

GoalRecommended Method
Check for missing valuesdf.isna()
Check for present valuesdf.notna()
Count missing per columndf.isna().sum()
Check if any missing existdf.isna().any().any()
Total missing countdf.isna().sum().sum()
Filter rows with missing datadf[df.isna().any(axis=1)]
Filter rows without missing datadf.dropna() or df[df.notna().all(axis=1)]

Summary

.isna() and .isnull() are 100% identical in Pandas. They are exact aliases that share the same implementation and detect the same missing value types: np.nan, None, and pd.NA. The same applies to their complements, .notna() and .notnull().

For consistency with modern Python conventions and official Pandas documentation, prefer isna() and notna() throughout your codebase.

The most important thing is to pick one style and stick with it so your code remains readable and predictable.