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.