summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2017-06-09 12:23:52 -0600
committerGitHub <noreply@github.com>2017-06-09 12:23:52 -0600
commitfa913a8ea6a8b363962dec6d656049a1371b53d9 (patch)
treea368b6ee1ac1bbffe50aa45981ec2dab293801e7 /numpy
parent18f69fdf3f0208ea26947b89edf60e7f83b0325d (diff)
parent0b060fd90f116fbf5b199603a11a4ce9e20c21c1 (diff)
downloadnumpy-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.py25
-rw-r--r--numpy/ma/tests/test_core.py17
-rw-r--r--numpy/ma/tests/test_old_ma.py156
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