Create masked array from list containing ma.masked

477 views Asked by At

If I have a (possibly multidimensional) Python list where each element is one of True, False, or ma.masked, what's the idiomatic way of turning this into a masked numpy array of bool?

Example:

>>> print(somefunc([[True, ma.masked], [False, True]]))
[[True --]
 [False True]]
1

There are 1 answers

0
hpaulj On

A masked array has to attributes, data and mask:

In [342]: arr = np.ma.masked_array([[True, False],[False,True]])
In [343]: arr
Out[343]: 
masked_array(
  data=[[ True, False],
        [False,  True]],
  mask=False,
  fill_value=True)

That starts without anything masked. Then as you suggest, assigning np.ma.masked to an element masks the slot:

In [344]: arr[0,1]=np.ma.masked
In [345]: arr
Out[345]: 
masked_array(
  data=[[True, --],
        [False, True]],
  mask=[[False,  True],
        [False, False]],
  fill_value=True)

Here the arr.mask has been changed from scalar False (applying to the whole array) to a boolean array of False, and then the selected item has been changed to True.

arr.data hasn't changed:

In [346]: arr.data[0,1]
Out[346]: False

Looks like this change to arr.mask occurs in data.__setitem__ at:

    if value is masked:
        # The mask wasn't set: create a full version.
        if _mask is nomask:
            _mask = self._mask = make_mask_none(self.shape, _dtype)
        # Now, set the mask to its value.
        if _dtype.names is not None:
            _mask[indx] = tuple([True] * len(_dtype.names))
        else:
            _mask[indx] = True
        return

It checks if the assignment values is this special constant, np.ma.masked, and it makes the full mask, and assigns True to an element.