Why do I sometimes get incorrect results when I compare one mask to another?
Let's say you have the following masked variable
a
(from package MV
):
>>> import MV
>>> import Numeric
>>> from Numeric import allclose
>>> data = Numeric.array([1., 2., 3., 1e20, -4., 7.])
>>> a = MV.masked_values(data, 1e20)
This produces a masked variable a
where the
data is the sequence given, and the mask for the
element given by 1e20
is set to "invalid".
The mask for a
is:
>>> a.mask()
[0,0,0,1,0,0,]
Now, let's say we used the Numeric.where
function
to generate an array showing which elements are greater than
1e19
>>> big_pts = Numeric.where(data > 1e19, 1, 0)
>>> big_pts
[0,0,0,1,0,0,]
From the output, you'd assume that the mask for a
and
the array big_pts
should test true, element-by-element.
This is the case when using the ==
operator:
>>> if a.mask() == big_pts: print 'true'
...
true
But you get the Numeric.allclose
function (which is generally a better way
of comparing two arrays):
>>> allclose( big_pts, a.mask() )
0
What gives? It appears this is because the type of the mask isn't
an integer array (i.e. its typecode is '1'
, the
numeral "one", not 'l'
, the letter "el").
To fix it, recast a.mask()
as an
integer array:
>>> big_pts.typecode()
'l'
>>> a.mask().typecode()
'1'
>>> allclose( big_pts, a.mask().astype(Numeric.Int) )
1
And everything works fine! Note too that you need to do this recasting of the mask type, even if you're comparing a mask to another mask:
>>> a = MV.masked_values(data, 1e20)
>>> allclose( a.mask(), a.mask() )
0
>>> allclose( a.mask().astype(Numeric.Int), a.mask().astype(Numeric.Int) )
1
Notes: This discussion applies to the version of MV with Numeric 23.0.