Skip to content

Python NumPy: How to Catch a NumPy Warning Like an Exception in Python

Learn how to convert NumPy warnings (like divide by zero or invalid operations) into catchable FloatingPointError exceptions using np.errstate(), np.seterr(), or warnings.catch_warnings() for robust error handling.

NumPy operations like dividing by zero, taking the logarithm of a negative number, or overflow in calculations produce warnings rather than raising exceptions. While warnings don't stop your program, they can indicate serious issues in your computations. In some cases, you want to catch these warnings and handle them just like exceptions - logging them, providing fallback values, or stopping execution.

This guide covers several methods to convert NumPy warnings into catchable exceptions.

Understanding the Problem

By default, NumPy operations that produce invalid results emit a warning but continue execution:

import numpy as np

arr = np.array([1.0, 2.0, 3.0])
result = arr / 0

print(result)

Output:

RuntimeWarning: divide by zero encountered in divide
[inf inf inf]

The program continues with inf values instead of stopping. In many scenarios, you want to catch this and handle it explicitly.

The np.errstate() context manager lets you control how NumPy handles floating-point errors within a specific block of code. Setting an error category to 'raise' causes NumPy to raise a FloatingPointError exception:

import numpy as np

arr = np.array([1.0, 5.0, 4.0])

with np.errstate(divide='raise'):
    try:
        result = arr / 0
    except FloatingPointError:
        print("❌ Error: Division by zero detected!")

Output:

❌ Error: Division by zero detected!

Available Error Categories

You can control different types of floating-point errors independently:

import numpy as np

with np.errstate(divide='raise', invalid='raise', over='raise', under='raise'):
    try:
        result = np.sqrt(-1)  # Invalid operation
    except FloatingPointError as e:
        print(f"Caught: {e}")

Output:

Caught: invalid value encountered in sqrt
Category Triggers On Example
divide Division by zero 1.0 / 0
invalid Invalid operation (e.g., 0/0, sqrt(-1)) np.sqrt(-1)
over Overflow (result too large) np.float64(1e308) * 10
under Underflow (result too small) np.float64(1e-308) / 1e308

Setting All Categories at Once

import numpy as np

with np.errstate(all='raise'):
    try:
        result = np.array([0.0]) / np.array([0.0])  # 0/0 = invalid
    except FloatingPointError as e:
        print(f"Caught: {e}")

Output:

Caught: invalid value encountered in divide

Using np.seterr() for Global Configuration

np.seterr() changes how NumPy handles floating-point errors globally for the entire program:

import numpy as np

original_settings = np.seterr(all='raise')

try:
    result = np.array([1.0, 2.0]) / 0
except FloatingPointError as e:
    print(f"Caught globally: {e}")

np.seterr(**original_settings)

Output:

Caught globally: divide by zero encountered in divide

Available Actions

Action Behavior
'raise' Raise a FloatingPointError exception
'warn' Print a RuntimeWarning (default)
'ignore' Silently ignore the issue
'call' Call a custom function
'print' Print a warning to stdout
'log' Log the warning

Using the warnings Module

Python's built-in warnings module can convert warnings into exceptions, including NumPy's RuntimeWarning:

import warnings
import numpy as np

with warnings.catch_warnings():
    warnings.simplefilter("error")  # Treat all warnings as errors

    try:
        result = np.array([1.0, 2.0, 3.0]) / 0
    except RuntimeWarning as e:
        print(f"Caught warning: {e}")

Output:

Caught warning: divide by zero encountered in divide

Filtering Specific Warning Types

You can target only specific warning categories:

import warnings
import numpy as np

with warnings.catch_warnings():
    warnings.filterwarnings("error", category=RuntimeWarning)

    try:
        result = np.log(-1)  # Produces RuntimeWarning
    except RuntimeWarning as e:
        print(f"Caught: {e}")

Output:

Caught: invalid value encountered in log

Practical Example: Safe Division with Fallback

Here's a real-world function that catches division-related warnings and provides fallback values:

import numpy as np

def safe_divide(a, b, default=0.0):
    """Divide arrays a/b, replacing invalid results with a default value."""
    with np.errstate(divide='raise', invalid='raise'):
        try:
            result = a / b
        except FloatingPointError:
            result = np.where(b != 0, a / np.where(b != 0, b, 1), default)
    return result

numerator = np.array([10, 20, 30, 0])
denominator = np.array([2, 0, 5, 0])

result = safe_divide(numerator, denominator, default=-1)
print("Result:", result)

Output:

Result: [ 5. -1.  6. -1.]

Positions where the denominator is zero are replaced with the default value (-1) instead of producing inf or nan.

Practical Example: Data Validation Pipeline

import numpy as np

def validate_computation(data):
    """Run computation with strict error checking."""
    errors = []

    with np.errstate(all='raise'):
        try:
            ratios = data['values'] / data['weights']
        except FloatingPointError:
            errors.append("Division error in ratio calculation")
            ratios = np.zeros_like(data['values'])

        try:
            log_values = np.log(data['values'])
        except FloatingPointError:
            errors.append("Invalid values for logarithm")
            log_values = np.full_like(data['values'], np.nan)

    return {
        'ratios': ratios,
        'log_values': log_values,
        'errors': errors
    }

data = {
    'values': np.array([10.0, 0.0, -5.0, 20.0]),
    'weights': np.array([2.0, 0.0, 1.0, 4.0])
}

result = validate_computation(data)
print("Ratios:", result['ratios'])
print("Log values:", result['log_values'])
print("Errors:", result['errors'])

Output:

Ratios: [0. 0. 0. 0.]
Log values: [nan nan nan nan]
Errors: ['Division error in ratio calculation', 'Invalid values for logarithm']

Comparison of Methods

Method Scope Exception Type Best For
np.errstate() Local (with block) FloatingPointError Recommended - localized handling
np.seterr() Global FloatingPointError Program-wide settings
warnings.catch_warnings() Local (with block) RuntimeWarning Catching all Python warnings

Conclusion

NumPy warnings can mask serious computation errors in your data pipeline.

  • Using np.errstate() with 'raise' is the safest and most Pythonic approach: it converts floating-point issues into catchable FloatingPointError exceptions within a scoped block, without affecting the rest of your program.

  • Use np.seterr() when you need global settings

  • Use warnings module when you want to catch broader Python warning categories.

By treating warnings as exceptions where appropriate, you ensure that invalid computations are detected and handled rather than silently producing incorrect results.

Navigation