Use np.ma.equal
instead of ==
- see end.
========================
A masked array consists of a data
array and a mask array. Often the masked array is used in other operations by 'filling' the masked values with something innocuous, or by compressing them out. I'm not entirely sure what's going on with this ==
test, but let's look at the calculations.
Your striding produces an array:
In [614]: A
Out[614]:
array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5]])
In [615]: b
Out[615]: array([2, 3, 4])
In [612]: A==b
Out[612]:
array([[False, False, False],
[ True, True, True],
[False, False, False]], dtype=bool)
The masked array has data
and mask
In [616]: c
Out[616]:
masked_array(data = [2 -- 4],
mask = [False True False],
fill_value = 999999)
In [617]: c.data
Out[617]: array([ 2, 99, 4])
In [618]: c.mask
Out[618]: array([False, True, False], dtype=bool)
In [619]: (A==c).data
Out[619]:
array([[False, False, False],
[ True, False, True],
[False, False, False]], dtype=bool)
This data
is we'd expect from A==c.data
. The center 99
does not match.
But it looks like the mask is applied to the whole boolean array as though c
where a column array - it's masking the 2nd row, rather than the 2nd column.
In [624]: A==c
Out[624]:
masked_array(data =
[[False False False]
[-- -- --]
[False False False]],
mask =
[False True False],
fill_value = True)
My first impression is that that is an error. But I'll have to dig more.
The data
of A==c
is 2d, but the mask is 1d.
If I replicated c
to 3 rows, then I get the desired results:
In [638]: c[None,:]*np.array([1,1,1])[:,None]
Out[638]:
masked_array(data =
[[2 -- 4]
[2 -- 4]
[2 -- 4]],
mask =
[[False True False]
[False True False]
[False True False]],
fill_value = 999999)
In [639]: c1=c[None,:]*np.array([1,1,1])[:,None]
In [640]: A==c1
Out[640]:
masked_array(data =
[[False -- False]
[True -- True]
[False -- False]],
mask =
[[False True False]
[False True False]
[False True False]],
fill_value = True)
In [641]: (A==c1).all(axis=1)
Out[641]:
masked_array(data = [False True False],
mask = [False False False],
fill_value = True)
I don't know if there's a cleaner way of doing this, but it indicates the direction such as solution needs to take.
============
np.ma.equal
does what we want (==
comparison with correct mask)
In [645]: np.ma.equal(A,c)
Out[645]:
masked_array(data =
[[False -- False]
[True -- True]
[False -- False]],
mask =
[[False True False]
[False True False]
[False True False]],
fill_value = 999999)
In [646]: np.ma.equal(A,c).any(axis=1)
Out[646]:
masked_array(data = [False True False],
mask = [False False False],
fill_value = True)
np.ma.equal
is a masked-aware version of np.equal
, which a ufunc
version of the element by element ==
operator.