Python NumPy: How to Compare Two NumPy Arrays in Python
When working with numerical data in Python, comparing arrays is a fundamental operation. Whether you're validating computation results, checking data integrity, testing scientific simulations, or filtering datasets, NumPy provides efficient and flexible methods to compare arrays of any size and shape.
In this guide, you'll learn multiple ways to compare two NumPy arrays - from simple equality checks to element-wise comparisons and approximate matching for floating-point data.
Using np.array_equal() (Recommended for Equality)
The np.array_equal() function is the simplest and most reliable way to check if two arrays are identical. It verifies that both arrays have the same shape and that every element matches exactly.
import numpy as np
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[1, 2], [3, 4]])
arr3 = np.array([[1, 2], [3, 5]])
print(np.array_equal(arr1, arr2))
print(np.array_equal(arr1, arr3))
Output:
True
False
This function returns a single True or False value, making it ideal for conditional checks:
import numpy as np
expected = np.array([1, 2, 3])
result = np.array([1, 2, 3])
if np.array_equal(expected, result):
print("Test passed: arrays are identical.")
else:
print("Test failed: arrays differ.")
Output:
Test passed: arrays are identical.
np.array_equal() is the preferred method for checking exact equality. It handles shape mismatches gracefully (returns False instead of raising an error) and works with arrays of any dimension.
Using == with .all()
The == operator performs an element-wise comparison, returning a boolean array of the same shape. Chain it with .all() to check if every element matches:
import numpy as np
arr1 = np.array([10, 20, 30, 40])
arr2 = np.array([10, 20, 30, 40])
arr3 = np.array([10, 20, 99, 40])
# Element-wise comparison
print("Element-wise (arr1 vs arr2):", arr1 == arr2)
print("All equal:", (arr1 == arr2).all())
print("\nElement-wise (arr1 vs arr3):", arr1 == arr3)
print("All equal:", (arr1 == arr3).all())
Output:
Element-wise (arr1 vs arr2): [ True True True True]
All equal: True
Element-wise (arr1 vs arr3): [ True True False True]
All equal: False
The boolean array from == is useful on its own - it shows you exactly which elements differ, not just whether the arrays are equal.
Using == on arrays with different shapes can trigger broadcasting, which may produce unexpected results instead of an error:
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
# Broadcasting: arr1 is compared to each row of arr2
print(arr1 == arr2)
Output:
[[ True True True]
[False False False]]
This doesn't raise an error - it broadcasts arr1 across the rows of arr2. Use np.array_equal() if you want a strict shape-and-content check.
Using np.allclose() for Floating-Point Comparison
Floating-point arithmetic often introduces tiny rounding errors. Direct equality comparison (==) can fail even when values are effectively the same:
import numpy as np
a = np.array([0.1 + 0.2])
b = np.array([0.3])
print(f"a = {a[0]:.20f}")
print(f"b = {b[0]:.20f}")
print(f"a == b: {np.array_equal(a, b)}")
Output:
a = 0.30000000000000004441
b = 0.29999999999999998890
a == b: False
The values differ by a tiny floating-point error. np.allclose() solves this by checking if elements are equal within a tolerance:
import numpy as np
a = np.array([0.1 + 0.2, 1.0000001, 3.14])
b = np.array([0.3, 1.0, 3.14])
print(f"Exact equal: {np.array_equal(a, b)}")
print(f"Approximately equal: {np.allclose(a, b)}")
Output:
Exact equal: False
Approximately equal: True
Syntax:
np.allclose(a, b, rtol=1e-05, atol=1e-08)
atol- absolute tolerance (default:1e-08)rtol- relative tolerance (default:1e-05)
You can adjust tolerances for your specific needs:
import numpy as np
a = np.array([1.0, 2.0, 3.0])
b = np.array([1.01, 2.02, 3.03])
print(f"Default tolerance: {np.allclose(a, b)}")
print(f"Looser tolerance: {np.allclose(a, b, atol=0.05)}")
Output:
Default tolerance: False
Looser tolerance: True
Always use np.allclose() instead of == when comparing arrays that result from floating-point calculations - including trigonometric functions, matrix operations, or division.
Element-Wise Comparison Operators
NumPy supports standard comparison operators for element-by-element analysis. These return boolean arrays showing the result at each position:
import numpy as np
scores_a = np.array([85, 92, 78, 95])
scores_b = np.array([90, 88, 78, 91])
print(f"Scores A: {scores_a}")
print(f"Scores B: {scores_b}")
print(f"A > B: {scores_a > scores_b}")
print(f"A < B: {scores_a < scores_b}")
print(f"A >= B: {scores_a >= scores_b}")
print(f"A == B: {scores_a == scores_b}")
Output:
Scores A: [85 92 78 95]
Scores B: [90 88 78 91]
A > B: [False True False True]
A < B: [ True False False False]
A >= B: [False True True True]
A == B: [False False True False]
Using NumPy Comparison Functions
NumPy also provides equivalent functions that are useful in functional-style code:
import numpy as np
a = np.array([10, 20, 30])
b = np.array([15, 20, 25])
print(f"Greater: {np.greater(a, b)}")
print(f"Less: {np.less(a, b)}")
print(f"Equal: {np.equal(a, b)}")
print(f"Not equal: {np.not_equal(a, b)}")
Output:
Greater: [False False True]
Less: [ True False False]
Equal: [False True False]
Not equal: [ True False True]
Finding Where Arrays Differ with np.where()
To identify the positions where two arrays differ, combine comparison operators with np.where():
import numpy as np
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([1, 9, 3, 9, 5])
diff_indices = np.where(arr1 != arr2)[0]
print(f"Arrays differ at indices: {diff_indices}")
for idx in diff_indices:
print(f" Index {idx}: {arr1[idx]} vs {arr2[idx]}")
Output:
Arrays differ at indices: [1 3]
Index 1: 2 vs 9
Index 3: 4 vs 9
Counting Differences
To count how many elements differ between two arrays:
import numpy as np
arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8])
arr2 = np.array([1, 2, 0, 4, 0, 6, 0, 8])
num_differences = np.sum(arr1 != arr2)
total_elements = arr1.size
match_percentage = (1 - num_differences / total_elements) * 100
print(f"Differences: {num_differences} out of {total_elements}")
print(f"Match rate: {match_percentage:.1f}%")
Output:
Differences: 3 out of 8
Match rate: 62.5%
Comparing Arrays with NaN Values
NaN values require special handling because NaN != NaN by IEEE 754 rules:
import numpy as np
a = np.array([1.0, np.nan, 3.0])
b = np.array([1.0, np.nan, 3.0])
print(f"array_equal: {np.array_equal(a, b)}")
print(f"Element ==: {a == b}")
Output:
array_equal: False
Element ==: [ True False True]
To treat NaN values at the same position as equal, use np.array_equal() with the equal_nan parameter (NumPy 1.19+):
import numpy as np
a = np.array([1.0, np.nan, 3.0])
b = np.array([1.0, np.nan, 3.0])
print(np.array_equal(a, b, equal_nan=True))
Output:
True
Quick Comparison of Methods
| Method | Returns | Handles NaN | Handles Tolerance | Best For |
|---|---|---|---|---|
np.array_equal() | Single bool | ✅ (equal_nan) | ❌ | Exact equality check |
== + .all() | Single bool | ❌ | ❌ | Equality with element-wise detail |
np.allclose() | Single bool | ✅ (equal_nan) | ✅ | Floating-point comparison |
>, <, >=, <= | Boolean array | ❌ | ❌ | Element-wise magnitude comparison |
np.where(a != b) | Index array | ❌ | ❌ | Finding positions of differences |
Conclusion
NumPy provides a comprehensive set of tools for comparing arrays, each suited to different scenarios:
- Use
np.array_equal()for straightforward exact equality checks - it's clean, reliable, and handles shape mismatches gracefully. - Use
np.allclose()when comparing floating-point arrays that may have tiny rounding differences. - Use
==with.all()when you want to see the element-wise boolean result before deciding on overall equality. - Use comparison operators (
>,<,>=,<=) for element-wise magnitude comparisons. - Use
np.where()to find the exact positions where arrays differ.
For most use cases, np.array_equal() for integer/exact data and np.allclose() for floating-point data will cover your needs.