Skip to content

How to Check for Infinity and NaN in Python

Learn how to detect NaN and infinity values in Python using math.isnan(), math.isinf(), and NumPy/Pandas functions for scalars, arrays, and DataFrames.

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')

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

if math.isinf(val_inf):
    print("Value is infinite")

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])

print(np.isnan(arr))        # [False False  True False False False]

print(np.isinf(arr))        # [False False False  True  True False]

print(np.isfinite(arr))     # [ True  True False False False  True]

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])

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

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

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

print(df['values'].isna())

print(np.isinf(df['values']))

df_no_nan = df.dropna()

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()
    
    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):
    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

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

Function Detects Best For
math.isnan() NaN only Single scalar values
math.isinf() Infinity only Single scalar values
math.isfinite() Valid finite numbers Input validation
np.isnan() NaN in arrays NumPy arrays
np.isinf() Infinity in arrays NumPy arrays
np.isfinite() Finite values in arrays Array filtering
pd.isna() NaN and None Pandas 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.

Navigation