summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/1.14.0-notes.rst8
-rw-r--r--numpy/ma/core.py12
-rw-r--r--numpy/ma/tests/test_core.py31
3 files changed, 41 insertions, 10 deletions
diff --git a/doc/release/1.14.0-notes.rst b/doc/release/1.14.0-notes.rst
index b5d133081..0ba2edd96 100644
--- a/doc/release/1.14.0-notes.rst
+++ b/doc/release/1.14.0-notes.rst
@@ -94,6 +94,14 @@ This is for pytest compatibility in the case of duplicate test file names in
the different directories. As a result, ``run_module_suite`` no longer works,
i.e., ``python <path-to-test-file>`` results in an error.
+``MaskedArray.squeeze`` never returns ``np.ma.masked``
+------------------------------------------------------
+``np.squeeze`` is documented as returning a view, but the masked variant would
+sometimes return ``masked``, which is not a view. This has been fixed, so that
+the result is always a view on the original masked array.
+This breaks any code that used ``masked_arr.squeeze() is np.ma.masked``, but
+fixes code that writes to the result of `.squeeze()`.
+
C API changes
=============
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 44096a25a..deddacfdc 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -2555,14 +2555,10 @@ def _arraymethod(funcname, onmask=True):
result = result.view(type(self))
result._update_from(self)
mask = self._mask
- if result.ndim:
- if not onmask:
- result.__setmask__(mask)
- elif mask is not nomask:
- result.__setmask__(getattr(mask, funcname)(*args, **params))
- else:
- if mask.ndim and (not mask.dtype.names and mask.all()):
- return masked
+ if not onmask:
+ result.__setmask__(mask)
+ elif mask is not nomask:
+ result.__setmask__(getattr(mask, funcname)(*args, **params))
return result
methdoc = getattr(ndarray, funcname, None) or getattr(np, funcname, None)
if methdoc is not None:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index f755fd8b7..e3c35cf81 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -445,6 +445,12 @@ class TestMaskedArray(object):
assert_not_equal(y._data.ctypes.data, x._data.ctypes.data)
assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data)
+ def test_copy_0d(self):
+ # gh-9430
+ x = np.ma.array(43, mask=True)
+ xc = x.copy()
+ assert_equal(xc.mask, True)
+
def test_copy_on_python_builtins(self):
# Tests copy works on python builtins (issue#8019)
assert_(isMaskedArray(np.ma.copy([1,2,3])))
@@ -3185,8 +3191,23 @@ class TestMaskedArrayMethods(object):
data = masked_array([[1, 2, 3]], mask=[[1, 1, 1]])
assert_equal(data.squeeze(), [1, 2, 3])
assert_equal(data.squeeze()._mask, [1, 1, 1])
- data = masked_array([[1]], mask=True)
- assert_(data.squeeze() is masked)
+
+ # normal ndarrays return a view
+ arr = np.array([[1]])
+ arr_sq = arr.squeeze()
+ assert_equal(arr_sq, 1)
+ arr_sq[...] = 2
+ assert_equal(arr[0,0], 2)
+
+ # so maskedarrays should too
+ m_arr = masked_array([[1]], mask=True)
+ m_arr_sq = m_arr.squeeze()
+ assert_(m_arr_sq is not np.ma.masked)
+ assert_equal(m_arr_sq.mask, True)
+ m_arr_sq[...] = 2
+ # TODO: mask isn't copied to/from views yet in maskedarray, so we can
+ # only check the data
+ assert_equal(m_arr.data[0,0], 2)
def test_swapaxes(self):
# Tests swapaxes on MaskedArrays.
@@ -3369,6 +3390,12 @@ class TestMaskedArrayMethods(object):
assert_equal(MaskedArray.cumsum(marray.T, 0), control.cumsum(0))
+ def test_arraymethod_0d(self):
+ # gh-9430
+ x = np.ma.array(42, mask=True)
+ assert_equal(x.T.mask, x.mask)
+ assert_equal(x.T.data, x.data)
+
class TestMaskedArrayMathMethods(object):