NumPy isclose(): Floating-Point Tolerance, NaN, and Arrays

Quick answer: Use np.isclose(a, b) when floating-point values should be considered equal within a tolerance. The comparison combines a relative tolerance with an absolute tolerance, returns an element-wise boolean mask for arrays, and needs an explicit NaN policy near zero or missing data.

Python Pool infographic explaining NumPy isclose relative tolerance absolute tolerance NaN and array masks
Floating-point equality needs a tolerance policy: isclose() combines relative and absolute tolerances and returns a boolean mask.

numpy.isclose() compares numbers element by element and returns booleans that show whether each pair is close enough within a tolerance.

The official NumPy documentation covers numpy.isclose(), numpy.allclose(), and numpy.isfinite().

Use isclose() when exact equality is too strict for floating-point math. Decimal fractions, measurement data, model output, and many numerical calculations can contain tiny differences that are harmless.

The function checks the absolute difference between two inputs against a tolerance rule. The key arguments are rtol, atol, and equal_nan.

rtol is relative tolerance, so it scales with the size of the reference value. atol is absolute tolerance, so it gives a fixed allowed difference near zero.

The result has the same broadcasted shape as the compared inputs. That makes isclose() useful for masks, diagnostics, tests, and filtering rows that are near a target value.

Choose tolerances deliberately. A tolerance that is too small can reject valid numeric results, while a tolerance that is too large can hide meaningful differences.

If you need one boolean for the entire array, use np.allclose(). If you need a boolean array that shows each position, use np.isclose().

A good review habit is to print the difference beside the close check while tuning tolerances. That makes it clear whether a false result comes from a real mismatch or from a tolerance that is too strict for the data scale.

For production code, document the reason for the chosen tolerance near the comparison. Future readers should know whether the tolerance represents rounding, measurement precision, simulation noise, or an accepted business threshold.

Compare Two Floating-Point Values

A classic use case is checking a result that cannot be represented exactly in binary floating-point.

import numpy as np

left = 0.1 + 0.2
right = 0.3

print(left == right)
print(np.isclose(left, right))

The equality check can be false even when the values are mathematically the same for practical purposes.

isclose() treats the tiny representation difference as acceptable under the default tolerances.

This pattern is useful in tests, tutorials, and numerical code where exact equality would create misleading failures.

It is especially helpful when values were produced by several arithmetic operations. Each operation can add a very small representation difference, so comparing the final result with == often says more about storage details than about the calculation.

Compare Arrays Element By Element

When arrays are passed, isclose() returns a boolean array.

import numpy as np

actual = np.array([1.0, 2.000001, 3.2])
expected = np.array([1.0, 2.0, 3.0])

result = np.isclose(actual, expected)

print(result)

The output marks each position as close or not close.

This is more informative than a single pass-or-fail answer because it shows where the mismatch occurs.

Use this form when debugging numeric pipelines, comparing calculated columns, or checking model predictions against expected values.

The boolean output can also be logged or counted. For example, summing a boolean mask tells you how many positions passed the closeness test, while negating it with ~result points to the positions that need inspection.

Python Pool infographic showing two floating-point values, absolute error, and relative scale
Float values: Two floating-point values, absolute error, and relative scale.

Set rtol And atol

Custom tolerances make the comparison match the scale of your data.

import numpy as np

measured = np.array([100.0, 100.4, 101.2])
target = 100.0

loose = np.isclose(measured, target, rtol=0.02, atol=0.0)
strict = np.isclose(measured, target, rtol=0.001, atol=0.0)

print(loose)
print(strict)

The looser tolerance accepts a wider percentage difference from the target.

The stricter tolerance rejects values that are farther away.

For values near zero, do not rely only on relative tolerance. Add an absolute tolerance that represents the smallest meaningful difference in your problem.

This is one of the most common practical details with isclose(). Relative tolerance works well for large values, but a tiny reference value leaves little room for relative error. In those cases, atol usually carries the comparison.

Handle NaN Values

By default, NaN is not considered close to another NaN.

import numpy as np

first = np.array([1.0, np.nan, 3.0])
second = np.array([1.0, np.nan, 3.1])

default_check = np.isclose(first, second)
nan_check = np.isclose(first, second, equal_nan=True)

print(default_check)
print(nan_check)

Set equal_nan=True when matching missing values should count as a close result.

Leave it false when a missing value should be treated as a mismatch.

This distinction matters in data cleanup, validation checks, and comparisons between imported datasets.

If missing values have already been approved as matching gaps, equal_nan=True keeps the comparison concise. If missing values should trigger review, leave the default behavior unchanged and handle those positions separately.

Python Pool infographic mapping rtol and atol through relative and absolute tolerance thresholds
Tolerance rule: Rtol and atol through relative and absolute tolerance thresholds.

Use isclose As A Mask

Because the result is boolean, it can select values near a target.

import numpy as np

readings = np.array([9.95, 10.02, 10.5, 9.99])
target = 10.0

mask = np.isclose(readings, target, atol=0.05)
near_target = readings[mask]

print(mask)
print(near_target)

This keeps only the values within 0.05 of the target.

The same pattern works for sensor readings, rounded reports, repeated simulations, and threshold-based checks.

Use a mask when you need the matching values, not just a true-or-false statement about the whole array.

This approach is also useful before plotting or reporting. You can separate near-target readings from outliers, then inspect the outliers with their original positions still available from the mask.

Compare isclose And allclose

isclose() answers position by position. allclose() returns one boolean for the whole comparison.

import numpy as np

actual = np.array([1.0, 2.000001, 3.0])
expected = np.array([1.0, 2.0, 3.0])

per_item = np.isclose(actual, expected)
whole_array = np.allclose(actual, expected)

print(per_item)
print(whole_array)

Use isclose() when you need to locate differences.

Use allclose() when the whole array should pass or fail as one unit.

In short, np.isclose(a, b) is the right tool for tolerance-aware element checks, and np.allclose(a, b) is the right tool for a single array-level answer.

Python Pool infographic comparing NaN, infinity, equal_nan, signed zero, and array comparison
Special values: NaN, infinity, equal_nan, signed zero, and array comparison.

Compare Scalars And Arrays

Floating-point calculations can differ by tiny representation or algorithmic errors, so exact == comparisons are often too strict. isclose() applies the same tolerance rule element by element and broadcasts compatible shapes.

import numpy as np

print(np.isclose(0.1 + 0.2, 0.3))

expected = np.array([1.0, 2.0, 3.0])
actual = np.array([1.0, 2.000001, 2.99])
print(np.isclose(actual, expected))

Choose rtol And atol

The default relation is approximately |a-b| <= atol + rtol * |b|. A relative tolerance scales with the reference value, while an absolute tolerance controls comparisons near zero. Set them from the measurement precision or numerical error budget rather than copying defaults blindly.

import numpy as np

expected = np.array([0.0, 1000.0])
actual = np.array([1e-7, 1000.5])
print(np.isclose(actual, expected, rtol=1e-4, atol=1e-6))
Python Pool infographic testing shape, broadcasting, scale, dtype, and assertion output
Closeness checks: Shape, broadcasting, scale, dtype, and assertion output.

Handle NaN And Infinity

NaN is not equal to itself under ordinary comparisons. Pass equal_nan=True only when matching NaN positions represent the same missing-data condition. Positive and negative infinity compare close only to the same infinity, not to a large finite number.

import numpy as np

left = np.array([np.nan, np.inf, 10.0])
right = np.array([np.nan, np.inf, 10.0001])
print(np.isclose(left, right))
print(np.isclose(left, right, equal_nan=True))

Reduce A Boolean Mask Deliberately

isclose() answers per element. Use np.all() when every element must satisfy the tolerance, np.any() when one match is enough, or retain the mask to report which coordinates differ. Do not hide a failed element by reducing without checking its context.

import numpy as np

expected = np.array([1.0, 2.0, 3.0])
actual = np.array([1.0, 2.0, 3.1])
mask = np.isclose(actual, expected, atol=1e-6)
print(mask)
print(np.all(mask))
print(np.flatnonzero(~mask))

NumPy’s official isclose() reference defines the tolerance relation, broadcasting, equal_nan, and the asymmetry of the reference value.

For related floating-point comparisons, compare NumPy allclose() for one aggregate decision, NumPy infinity values for non-finite inputs, and NumPy log() when the comparison follows a logarithmic transformation.

Frequently Asked Questions

How do I compare floating-point values in NumPy?

Call np.isclose(a, b) and choose rtol and atol that reflect the scale and error budget of the data.

What is the difference between rtol and atol?

rtol scales with the reference value while atol supplies a fixed absolute tolerance for values near zero.

How do I compare arrays with NaN values?

Pass equal_nan=True when NaNs in corresponding positions should count as equal under the application rule.

Does np.isclose() return one boolean or an array?

It returns an element-wise boolean array for array inputs and a scalar boolean for scalar inputs, subject to broadcasting.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted