From a5a3457e3f1d9ec309107dafd331e2c6593e1ff1 Mon Sep 17 00:00:00 2001 From: Kyungdahm Yun Date: Wed, 5 Jun 2013 16:01:01 +0900 Subject: [PATCH 1/3] Force empty/ones/zeros_like() to copy mask As underlying `empty_like()` knows nothing about mask, it would be `_convert2ma`'s job to properly set up the output mask. `copy` argument is added to figure out which functions need this behavior. `ones_like()` and `zeros_like()` which were mere aliases of regular numpy functions now go through `_convert2ma` as well. Hopefully this fixes #3145, #2572. --- numpy/ma/core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 38076e8b33de..3c503afa33ad 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -7179,10 +7179,11 @@ class _convert2ma: """ __doc__ = None # - def __init__(self, funcname, params=None): + def __init__(self, funcname, params=None, copy=False): self._func = getattr(np, funcname) self.__doc__ = self.getdoc() self._extras = params or {} + self._copy = copy # def getdoc(self): "Return the doc of the function (from the doc of the method)." @@ -7208,21 +7209,23 @@ def __call__(self, a, *args, **params): result.fill_value = _extras.get("fill_value", None) if "hardmask" in common_params: result._hardmask = bool(_extras.get("hard_mask", False)) + if self._copy: + result._mask = result._mask.copy() return result arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False)) clip = np.clip diff = np.diff empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False)) -empty_like = _convert2ma('empty_like') +empty_like = _convert2ma('empty_like', copy=True) frombuffer = _convert2ma('frombuffer') fromfunction = _convert2ma('fromfunction') identity = _convert2ma('identity', params=dict(fill_value=None, hardmask=False)) indices = np.indices ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False)) -ones_like = np.ones_like +ones_like = _convert2ma('ones_like', copy=True) squeeze = np.squeeze zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False)) -zeros_like = np.zeros_like +zeros_like = _convert2ma('zeros_like', copy=True) ############################################################################### From 0908295edd33cc79df05e4d746d43ead9025522b Mon Sep 17 00:00:00 2001 From: Kyungdahm Yun Date: Thu, 6 Jun 2013 10:42:59 +0900 Subject: [PATCH 2/3] Include ones_like, zeros_like public for import * --- numpy/ma/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 3c503afa33ad..4c009a0b29c5 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -75,7 +75,7 @@ 'maximum_fill_value', 'mean', 'min', 'minimum', 'minimum_fill_value', 'mod', 'multiply', 'mvoid', 'negative', 'nomask', 'nonzero', 'not_equal', - 'ones', 'outer', 'outerproduct', + 'ones', 'ones_like', 'outer', 'outerproduct', 'power', 'prod', 'product', 'ptp', 'put', 'putmask', 'rank', 'ravel', 'remainder', 'repeat', 'reshape', 'resize', 'right_shift', 'round_', 'round', @@ -84,7 +84,7 @@ 'swapaxes', 'take', 'tan', 'tanh', 'trace', 'transpose', 'true_divide', 'var', 'where', - 'zeros'] + 'zeros', 'zeros_like'] MaskType = np.bool_ nomask = MaskType(0) From 95438183502aa87ebeeb9c56539798a0c4634759 Mon Sep 17 00:00:00 2001 From: Kyungdahm Yun Date: Thu, 6 Jun 2013 10:48:46 +0900 Subject: [PATCH 3/3] Add a regression test for #3145 --- numpy/ma/tests/test_regression.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/numpy/ma/tests/test_regression.py b/numpy/ma/tests/test_regression.py index eb301aa0531f..85753a66b506 100644 --- a/numpy/ma/tests/test_regression.py +++ b/numpy/ma/tests/test_regression.py @@ -70,5 +70,17 @@ def test_ddof_corrcoef(self): # ddof should not have an effect (it gets cancelled out) assert_allclose(r0.data, r1.data) + def test_like_mask_copy(self): + """Issue gh-3145""" + m = [False, False, False, True] + a = np.ma.array([1, 2, 3, 4], mask=m) + a_empty = np.ma.empty_like(a) + a_ones = np.ma.ones_like(a) + a_zeros = np.ma.zeros_like(a) + a.mask = False + assert_array_equal(a_empty.mask, m) + assert_array_equal(a_ones.mask, m) + assert_array_equal(a_zeros.mask, m) + if __name__ == "__main__": run_module_suite()