As @hpaulj wrote that the ma
module is implemented in Python, I looked at the sources and indeed found answers:
The numpy.ma implementation has a "hardmask" feature,
which prevents values from ever being unmasked by assigning a value.
This would be an internal array flag, named something like
'arr.flags.hardmask'.
If the hardmask feature is implemented, boolean indexing could
return a hardmasked array instead of a flattened array with the
arbitrary choice of C-ordering as it currently does. While this
improves the abstraction of the array significantly, it is not
a compatible change.
The following documentation of the hardmask
attribute could be found in my old checkout in maskedarray.baseclass.rst
, but it vanished after updating, which explains why it is missing on the website:
Returns whether the mask is hard (True
) or soft (False
).
When the mask is hard, masked entries cannot be unmasked.
(I will send a PR suggesting that this sentence is restored and extended with ".. by element assigment".)
Here's a demonstration session:
>>> import numpy
>>> x = numpy.arange(10)
>>> m = numpy.ma.masked_array(x, x>5)
>>> assert not m.hardmask
>>> m[8] = 42
>>> m
masked_array(data=[0, 1, 2, 3, 4, 5, --, --, 42, --],
mask=[False, False, False, False, False, False, True, True,
False, True],
fill_value=999999)
>>> hardened = numpy.ma.harden_mask(m)
>>> assert hardened.hardmask
>>> assert m.hardmask, 'harden_mask() affects AND returns the argument'
>>> m[9] = 23
>>> m
masked_array(data=[0, 1, 2, 3, 4, 5, --, --, 42, --],
mask=[False, False, False, False, False, False, True, True,
False, True],
fill_value=999999)
>>> m[:] = 23
>>> m
masked_array(data=[23, 23, 23, 23, 23, 23, --, --, 23, --],
mask=[False, False, False, False, False, False, True, True,
False, True],
fill_value=999999)