Comparing Masks

Question

Why do I sometimes get incorrect results when I compare one mask to another?

Answer

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 wrong answer when using 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.

Return to the Tips and Examples index page.

Updated: November 15, 2003 by Johnny Lin <email address>. License.