Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ This document explains the changes made to Iris for this release
:func:`~iris.fileformats.pp.save_pairs_from_cube` because it had no effect.
(:pull:`5783`)

#. `@stephenworsley`_ made masked arrays on Iris objects now compare as equal
precisely when all unmasked points are equal and when the masks are identical.
This is due to changes in :func:`~iris.util.array_equal` which previously
ignored masks entirely. (:pull:`4457`)


🚀 Performance Enhancements
===========================
Expand Down
7 changes: 6 additions & 1 deletion lib/iris/tests/unit/util/test_array_equal.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ def test_nd(self):
self.assertTrue(array_equal(array_a, array_b))
self.assertFalse(array_equal(array_a, array_c))

def test_masked_is_ignored(self):
def test_masked_is_not_ignored(self):
array_a = ma.masked_array([1, 2, 3], mask=[1, 0, 1])
array_b = ma.masked_array([2, 2, 2], mask=[1, 0, 1])
self.assertTrue(array_equal(array_a, array_b))

def test_masked_is_different(self):
array_a = ma.masked_array([1, 2, 3], mask=[1, 0, 1])
array_b = ma.masked_array([1, 2, 2], mask=[0, 0, 1])
self.assertFalse(array_equal(array_a, array_b))

def test_fully_masked_arrays(self):
Expand Down
11 changes: 9 additions & 2 deletions lib/iris/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,17 +406,24 @@ def array_equal(array1, array2, withnans=False):

def normalise_array(array):
if not is_lazy_data(array):
array = np.asarray(array)
if not ma.isMaskedArray(array):
array = np.asanyarray(array)
return array

array1, array2 = normalise_array(array1), normalise_array(array2)

eq = array1.shape == array2.shape
if eq:
array1_masked = ma.is_masked(array1)
eq = array1_masked == ma.is_masked(array2)
if eq and array1_masked:
eq = np.array_equal(ma.getmask(array1), ma.getmask(array2))
if eq:
eqs = array1 == array2
if withnans and (array1.dtype.kind == "f" or array2.dtype.kind == "f"):
eqs = np.where(np.isnan(array1) & np.isnan(array2), True, eqs)
eq = bool(np.all(eqs))
eq = np.all(eqs)
eq = bool(eq) or eq is ma.masked

return eq

Expand Down