diff options
author | Greg Lucas <greg.m.lucas@gmail.com> | 2021-11-16 12:37:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-16 11:37:19 -0800 |
commit | b31a3a3fb05910abc2ee55d63255efdb2a2c383e (patch) | |
tree | 6a4bf7369908610274510f5b9ce7f999a026a205 /numpy | |
parent | 38558de9ecb8b0ec7982a956106713f921e2d3d5 (diff) | |
download | numpy-b31a3a3fb05910abc2ee55d63255efdb2a2c383e.tar.gz |
REV: Add MaskedArray creation from non nd-array back in (#20386)
* REV: Add MaskedArray creation from non nd-array back in
This code path was removed in beacb39. This adds back in the
MaskedArray portion of that commit. A test with a Quantity-like
(non inherited, but still acts like a MaskedArray) class for
this case.
* Update numpy/ma/core.py
Co-authored-by: Sebastian Berg <sebastian@sipsolutions.net>
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/ma/core.py | 6 | ||||
-rw-r--r-- | numpy/ma/tests/test_subclassing.py | 42 |
2 files changed, 48 insertions, 0 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 036d6312c..491c2c605 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -2837,6 +2837,12 @@ class MaskedArray(ndarray): _data = ndarray.view(_data, type(data)) else: _data = ndarray.view(_data, cls) + + # Handle the case where data is not a subclass of ndarray, but + # still has the _mask attribute like MaskedArrays + if hasattr(data, '_mask') and not isinstance(data, ndarray): + _data._mask = data._mask + # FIXME: should we set `_data._sharedmask = True`? # Process mask. # Type of the mask mdtype = make_mask_descr(_data.dtype) diff --git a/numpy/ma/tests/test_subclassing.py b/numpy/ma/tests/test_subclassing.py index 1af539625..83a9b2f51 100644 --- a/numpy/ma/tests/test_subclassing.py +++ b/numpy/ma/tests/test_subclassing.py @@ -343,3 +343,45 @@ class TestSubclassing: diff2 = arr1 - arr2 assert_('info' in diff2._optinfo) assert_(diff2._optinfo['info'] == 'test') + + +class ArrayNoInheritance: + """Quantity-like class that does not inherit from ndarray""" + def __init__(self, data, units): + self.magnitude = data + self.units = units + + def __getattr__(self, attr): + return getattr(self.magnitude, attr) + + +def test_array_no_inheritance(): + data_masked = np.ma.array([1, 2, 3], mask=[True, False, True]) + data_masked_units = ArrayNoInheritance(data_masked, 'meters') + + # Get the masked representation of the Quantity-like class + new_array = np.ma.array(data_masked_units) + assert_equal(data_masked.data, new_array.data) + assert_equal(data_masked.mask, new_array.mask) + # Test sharing the mask + data_masked.mask = [True, False, False] + assert_equal(data_masked.mask, new_array.mask) + assert_(new_array.sharedmask) + + # Get the masked representation of the Quantity-like class + new_array = np.ma.array(data_masked_units, copy=True) + assert_equal(data_masked.data, new_array.data) + assert_equal(data_masked.mask, new_array.mask) + # Test that the mask is not shared when copy=True + data_masked.mask = [True, False, True] + assert_equal([True, False, False], new_array.mask) + assert_(not new_array.sharedmask) + + # Get the masked representation of the Quantity-like class + new_array = np.ma.array(data_masked_units, keep_mask=False) + assert_equal(data_masked.data, new_array.data) + # The change did not affect the original mask + assert_equal(data_masked.mask, [True, False, True]) + # Test that the mask is False and not shared when keep_mask=False + assert_(not new_array.mask) + assert_(not new_array.sharedmask) |