diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2017-06-09 12:23:52 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-09 12:23:52 -0600 |
commit | fa913a8ea6a8b363962dec6d656049a1371b53d9 (patch) | |
tree | a368b6ee1ac1bbffe50aa45981ec2dab293801e7 /numpy | |
parent | 18f69fdf3f0208ea26947b89edf60e7f83b0325d (diff) | |
parent | 0b060fd90f116fbf5b199603a11a4ce9e20c21c1 (diff) | |
download | numpy-fa913a8ea6a8b363962dec6d656049a1371b53d9.tar.gz |
Merge pull request #5580 from jakirkham/fix_masked_array_views
BUG, DEP: Fix masked arrays to properly edit views. ( #5558 )
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/ma/core.py | 25 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 17 | ||||
-rw-r--r-- | numpy/ma/tests/test_old_ma.py | 156 |
3 files changed, 105 insertions, 93 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index b253b6f16..3f136896a 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -3357,8 +3357,6 @@ class MaskedArray(ndarray): _mask[indx] = tuple([True] * nbfields) else: _mask[indx] = True - if not self._isfield: - self._sharedmask = False return # Get the _data part of the new value @@ -3374,27 +3372,6 @@ class MaskedArray(ndarray): _mask = self._mask = make_mask_none(self.shape, _dtype) _mask[indx] = mval elif not self._hardmask: - # Unshare the mask if necessary to avoid propagation - # We want to remove the unshare logic from this place in the - # future. Note that _sharedmask has lots of false positives. - if not self._isfield: - notthree = getattr(sys, 'getrefcount', False) and (sys.getrefcount(_mask) != 3) - if self._sharedmask and not ( - # If no one else holds a reference (we have two - # references (_mask and self._mask) -- add one for - # getrefcount) and the array owns its own data - # copying the mask should do nothing. - (not notthree) and _mask.flags.owndata): - # 2016.01.15 -- v1.11.0 - warnings.warn( - "setting an item on a masked array which has a shared " - "mask will not copy the mask and also change the " - "original mask array in the future.\n" - "Check the NumPy 1.11 release notes for more " - "information.", - MaskedArrayFutureWarning, stacklevel=2) - self.unshare_mask() - _mask = self._mask # Set the data, then the mask _data[indx] = dval _mask[indx] = mval @@ -4659,7 +4636,7 @@ class MaskedArray(ndarray): if self._mask is nomask and getmask(values) is nomask: return - m = getmaskarray(self).copy() + m = getmaskarray(self) if getmask(values) is nomask: m.put(indices, False, mode=mode) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index c2b8d1403..bba8f2cb7 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -394,15 +394,26 @@ class TestMaskedArray(TestCase): y1._data.__array_interface__) self.assertTrue(y1a.mask is y1.mask) - y2 = array(x1, mask=m) + y2 = array(x1, mask=m3) self.assertTrue(y2._data.__array_interface__ == x1.__array_interface__) - self.assertTrue(y2._mask.__array_interface__ == m.__array_interface__) + self.assertTrue(y2._mask.__array_interface__ == m3.__array_interface__) self.assertTrue(y2[2] is masked) y2[2] = 9 self.assertTrue(y2[2] is not masked) - self.assertTrue(y2._mask.__array_interface__ != m.__array_interface__) + self.assertTrue(y2._mask.__array_interface__ == m3.__array_interface__) self.assertTrue(allequal(y2.mask, 0)) + y2a = array(x1, mask=m, copy=1) + self.assertTrue(y2a._data.__array_interface__ != x1.__array_interface__) + #self.assertTrue( y2a.mask is not m) + self.assertTrue(y2a._mask.__array_interface__ != m.__array_interface__) + self.assertTrue(y2a[2] is masked) + y2a[2] = 9 + self.assertTrue(y2a[2] is not masked) + #self.assertTrue( y2a.mask is not m) + self.assertTrue(y2a._mask.__array_interface__ != m.__array_interface__) + self.assertTrue(allequal(y2a.mask, 0)) + y3 = array(x1 * 1.0, mask=m) self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype) diff --git a/numpy/ma/tests/test_old_ma.py b/numpy/ma/tests/test_old_ma.py index 51fa6ac36..769e281d4 100644 --- a/numpy/ma/tests/test_old_ma.py +++ b/numpy/ma/tests/test_old_ma.py @@ -5,8 +5,7 @@ from functools import reduce import numpy as np import numpy.core.umath as umath import numpy.core.fromnumeric as fromnumeric -from numpy.testing import ( - TestCase, run_module_suite, assert_, suppress_warnings) +from numpy.testing import TestCase, run_module_suite, assert_ from numpy.ma.testutils import assert_array_equal from numpy.ma import ( MaskType, MaskedArray, absolute, add, all, allclose, allequal, alltrue, @@ -258,73 +257,98 @@ class TestMa(TestCase): def test_testCopySize(self): # Tests of some subtle points of copying and sizing. - with suppress_warnings() as sup: - sup.filter( - np.ma.core.MaskedArrayFutureWarning, - "setting an item on a masked array which has a " - "shared mask will not copy") - - n = [0, 0, 1, 0, 0] - m = make_mask(n) - m2 = make_mask(m) - self.assertTrue(m is m2) - m3 = make_mask(m, copy=1) - self.assertTrue(m is not m3) - - x1 = np.arange(5) - y1 = array(x1, mask=m) - self.assertTrue(y1._data is not x1) - self.assertTrue(allequal(x1, y1._data)) - self.assertTrue(y1.mask is m) - - y1a = array(y1, copy=0) - self.assertTrue(y1a.mask is y1.mask) - - y2 = array(x1, mask=m, copy=0) - self.assertTrue(y2.mask is m) - self.assertTrue(y2[2] is masked) - y2[2] = 9 - self.assertTrue(y2[2] is not masked) - self.assertTrue(y2.mask is not m) - self.assertTrue(allequal(y2.mask, 0)) - - y3 = array(x1 * 1.0, mask=m) - self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype) - - x4 = arange(4) - x4[2] = masked - y4 = resize(x4, (8,)) - self.assertTrue(eq(concatenate([x4, x4]), y4)) - self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])) - y5 = repeat(x4, (2, 2, 2, 2), axis=0) - self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3])) - y6 = repeat(x4, 2, axis=0) - self.assertTrue(eq(y5, y6)) + n = [0, 0, 1, 0, 0] + m = make_mask(n) + m2 = make_mask(m) + self.assertTrue(m is m2) + m3 = make_mask(m, copy=1) + self.assertTrue(m is not m3) + + x1 = np.arange(5) + y1 = array(x1, mask=m) + self.assertTrue(y1._data is not x1) + self.assertTrue(allequal(x1, y1._data)) + self.assertTrue(y1.mask is m) + + y1a = array(y1, copy=0) + self.assertTrue(y1a.mask is y1.mask) + + y2 = array(x1, mask=m3, copy=0) + self.assertTrue(y2.mask is m3) + self.assertTrue(y2[2] is masked) + y2[2] = 9 + self.assertTrue(y2[2] is not masked) + self.assertTrue(y2.mask is m3) + self.assertTrue(allequal(y2.mask, 0)) + + y2a = array(x1, mask=m, copy=1) + self.assertTrue(y2a.mask is not m) + self.assertTrue(y2a[2] is masked) + y2a[2] = 9 + self.assertTrue(y2a[2] is not masked) + self.assertTrue(y2a.mask is not m) + self.assertTrue(allequal(y2a.mask, 0)) + + y3 = array(x1 * 1.0, mask=m) + self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype) + + x4 = arange(4) + x4[2] = masked + y4 = resize(x4, (8,)) + self.assertTrue(eq(concatenate([x4, x4]), y4)) + self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])) + y5 = repeat(x4, (2, 2, 2, 2), axis=0) + self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3])) + y6 = repeat(x4, 2, axis=0) + self.assertTrue(eq(y5, y6)) def test_testPut(self): # Test of put - with suppress_warnings() as sup: - sup.filter( - np.ma.core.MaskedArrayFutureWarning, - "setting an item on a masked array which has a " - "shared mask will not copy") - d = arange(5) - n = [0, 0, 0, 1, 1] - m = make_mask(n) - x = array(d, mask=m) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is masked) - x[[1, 4]] = [10, 40] - self.assertTrue(x.mask is not m) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is not masked) - self.assertTrue(eq(x, [0, 10, 2, -1, 40])) - - x = array(d, mask=m) - x.put([0, 1, 2], [-1, 100, 200]) - self.assertTrue(eq(x, [-1, 100, 200, 0, 0])) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is masked) + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + m2 = m.copy() + x = array(d, mask=m) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is masked) + x[[1, 4]] = [10, 40] + self.assertTrue(x.mask is m) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is not masked) + self.assertTrue(eq(x, [0, 10, 2, -1, 40])) + + x = array(d, mask=m2, copy=True) + x.put([0, 1, 2], [-1, 100, 200]) + self.assertTrue(x.mask is not m2) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is masked) + self.assertTrue(eq(x, [-1, 100, 200, 0, 0])) + + def test_testPut2(self): + # Test of put + d = arange(5) + x = array(d, mask=[0, 0, 0, 0, 0]) + z = array([10, 40], mask=[1, 0]) + self.assertTrue(x[2] is not masked) + self.assertTrue(x[3] is not masked) + x[2:4] = z + self.assertTrue(x[2] is masked) + self.assertTrue(x[3] is not masked) + self.assertTrue(eq(x, [0, 1, 10, 40, 4])) + + d = arange(5) + x = array(d, mask=[0, 0, 0, 0, 0]) + y = x[2:4] + z = array([10, 40], mask=[1, 0]) + self.assertTrue(x[2] is not masked) + self.assertTrue(x[3] is not masked) + y[:] = z + self.assertTrue(y[0] is masked) + self.assertTrue(y[1] is not masked) + self.assertTrue(eq(y, [10, 40])) + self.assertTrue(x[2] is masked) + self.assertTrue(x[3] is not masked) + self.assertTrue(eq(x, [0, 1, 10, 40, 4])) def test_testMaPut(self): (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d |