Skip to main content

How to Check for Infinity and NaN in Python

In data science and scientific computing, you often encounter NaN (Not a Number) and inf (Infinity). These special values can produce unexpected results or crash your program if not handled correctly.

Because NaN != NaN evaluates to True in Python, you cannot check for it using the equality operator. Specialized functions are required.

Using the math Module

Python's built-in math library provides the standard way to check scalar values.

import math

val_nan = float('nan')
val_inf = float('inf')
val_neg_inf = float('-inf')

# Check for NaN
if math.isnan(val_nan):
print("Value is NaN")

# Check for Infinity (positive or negative)
if math.isinf(val_inf):
print("Value is infinite")

# Check if value is a valid finite number
# Returns True only if NOT NaN and NOT Inf
if math.isfinite(10.5):
print("Value is a valid finite number")

Output:

Value is NaN
Value is infinite
Value is a valid finite number

Distinguishing Positive and Negative Infinity

import math

def classify_number(value):
if math.isnan(value):
return "NaN"
elif math.isinf(value):
if value > 0:
return "Positive Infinity"
else:
return "Negative Infinity"
else:
return "Finite Number"

print(classify_number(float('inf'))) # Positive Infinity
print(classify_number(float('-inf'))) # Negative Infinity
print(classify_number(float('nan'))) # NaN
print(classify_number(42.0)) # Finite Number

Output:

Positive Infinity
Negative Infinity
NaN
Finite Number

Using NumPy for Arrays

For high-performance array operations, NumPy provides vectorized checking functions.

import numpy as np

arr = np.array([1.0, 0.0, np.nan, np.inf, -np.inf, 5.0])

# Check each element for NaN
print(np.isnan(arr)) # [False False True False False False]

# Check each element for Infinity
print(np.isinf(arr)) # [False False False True True False]

# Check each element for finite values
print(np.isfinite(arr)) # [ True True False False False True]

# Filter to keep only valid numbers
clean_arr = arr[np.isfinite(arr)]
print(clean_arr) # [1. 0. 5.]

Output:

[False False  True False False False]
[False False False True True False]
[ True True False False False True]
[1. 0. 5.]

Replacing Invalid Values

import numpy as np

data = np.array([1.0, np.nan, 3.0, np.inf, 5.0])

# Replace NaN with zero
data_no_nan = np.nan_to_num(data, nan=0.0)
print(data_no_nan) # [1. 0. 3. inf 5.]

# Replace both NaN and Inf
data_clean = np.nan_to_num(data, nan=0.0, posinf=999.0, neginf=-999.0)
print(data_clean) # [1. 0. 3. 999. 5.]

Output:

[1.00000000e+000 0.00000000e+000 3.00000000e+000 1.79769313e+308 5.00000000e+000]
[ 1. 0. 3. 999. 5.]

Using Pandas for DataFrames

When working with DataFrames, use Pandas functions that handle missing data robustly.

import pandas as pd
import numpy as np

# Create DataFrame with problematic values
df = pd.DataFrame({
'values': [1.0, np.nan, np.inf, -np.inf, 5.0],
'labels': ['a', 'b', 'c', 'd', 'e']
})

# Check for NaN (also catches None)
print(df['values'].isna())

# Check for Infinity
print(np.isinf(df['values']))

# Remove rows with NaN
df_no_nan = df.dropna()

# Remove rows with NaN or Inf
df_clean = df[np.isfinite(df['values'])]
print(df_clean)

Output:

0    False
1 True
2 False
3 False
4 False
Name: values, dtype: bool
0 False
1 False
2 True
3 True
4 False
Name: values, dtype: bool
values labels
0 1.0 a
4 5.0 e

Handling Mixed Data Types

import pandas as pd
import numpy as np

def sanitize_series(series):
"""Replace NaN and Inf with None for database insertion."""
result = series.copy()

# Handle numeric columns
if pd.api.types.is_numeric_dtype(series):
mask = ~np.isfinite(series.to_numpy(dtype=float, na_value=np.nan))
result[mask] = None

return result

data = pd.Series([1.0, np.nan, np.inf, 4.0])
clean_data = sanitize_series(data)
print(clean_data)

Output:

0    1.0
1 NaN
2 NaN
3 4.0
dtype: float64

Input Validation Pattern

Always validate numerical inputs before performing calculations.

import math

def safe_divide(numerator, denominator):
# Validate inputs
for name, value in [('numerator', numerator), ('denominator', denominator)]:
if not isinstance(value, (int, float)):
raise TypeError(f"{name} must be a number")
if not math.isfinite(value):
raise ValueError(f"{name} must be a finite number")

if denominator == 0:
raise ValueError("Cannot divide by zero")

return numerator / denominator

# Usage
try:
result = safe_divide(10, float('inf'))
except ValueError as e:
print(f"Invalid input: {e}")

Output:

Invalid input: denominator must be a finite number

Quick Reference

FunctionDetectsBest For
math.isnan()NaN onlySingle scalar values
math.isinf()Infinity onlySingle scalar values
math.isfinite()Valid finite numbersInput validation
np.isnan()NaN in arraysNumPy arrays
np.isinf()Infinity in arraysNumPy arrays
np.isfinite()Finite values in arraysArray filtering
pd.isna()NaN and NonePandas DataFrames

Summary

Use math.isfinite() to validate user input before calculations: it catches both NaN corruption and infinity overflow in a single check. For array operations, NumPy's vectorized functions provide better performance. When working with Pandas DataFrames, combine pd.isna() with np.isinf() to handle all edge cases.