diff options
| author | Eric Wieser <wieser.eric@gmail.com> | 2018-01-25 23:38:56 -0800 |
|---|---|---|
| committer | Eric Wieser <wieser.eric@gmail.com> | 2018-01-25 23:38:56 -0800 |
| commit | 56848bbd2a56209a6ea836fb23e57061825b3052 (patch) | |
| tree | facd9d03bad27a263b5f8852fc8433b6ad250c92 | |
| parent | 8a772dd80929aa556c6c01b9025f3c1da0666938 (diff) | |
| download | numpy-56848bbd2a56209a6ea836fb23e57061825b3052.tar.gz | |
BUG: Calling ufuncs with a positional output argument causes the result to inherit the output's mask
This brings `np.add(a, b, out)` in line with `np.add(a, b, out=out)`.
These previously differed because gh-10459 causes them to call __array_wrap__ in different ways (with and without the output argument in the context tuple, respectively).
Since the data in the `out` argument is never used by ufuncs, it seems consistent that the mask should not be either.
| -rw-r--r-- | numpy/ma/core.py | 12 | ||||
| -rw-r--r-- | numpy/ma/tests/test_core.py | 25 |
2 files changed, 32 insertions, 5 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 719961d1b..56c761da1 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -3029,18 +3029,20 @@ class MaskedArray(ndarray): if context is not None: result._mask = result._mask.copy() - (func, args, _) = context - m = reduce(mask_or, [getmaskarray(arg) for arg in args]) + func, args, out_i = context + # args sometimes contains outputs (gh-10459), which we don't want + input_args = args[:func.nin] + m = reduce(mask_or, [getmaskarray(arg) for arg in input_args]) # Get the domain mask domain = ufunc_domain.get(func, None) if domain is not None: # Take the domain, and make sure it's a ndarray - if len(args) > 2: + if len(input_args) > 2: with np.errstate(divide='ignore', invalid='ignore'): - d = filled(reduce(domain, args), True) + d = filled(reduce(domain, input_args), True) else: with np.errstate(divide='ignore', invalid='ignore'): - d = filled(domain(*args), True) + d = filled(domain(*input_args), True) if d.any(): # Fill the result where the domain is wrong diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index 8c631d95d..4c6bb2b42 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -5057,6 +5057,31 @@ def test_ufunc_with_output(): assert_(y is x) +def test_ufunc_with_out_varied(): + """ Test that masked arrays are immune to gh-10459 """ + # the mask of the output should not affect the result, however it is passed + a = array([ 1, 2, 3], mask=[1, 0, 0]) + b = array([10, 20, 30], mask=[1, 0, 0]) + out = array([ 0, 0, 0], mask=[0, 0, 1]) + expected = array([11, 22, 33], mask=[1, 0, 0]) + + out_pos = out.copy() + res_pos = np.add(a, b, out_pos) + + out_kw = out.copy() + res_kw = np.add(a, b, out=out_kw) + + out_tup = out.copy() + res_tup = np.add(a, b, out=(out_tup,)) + + assert_equal(res_kw.mask, expected.mask) + assert_equal(res_kw.data, expected.data) + assert_equal(res_tup.mask, expected.mask) + assert_equal(res_tup.data, expected.data) + assert_equal(res_pos.mask, expected.mask) + assert_equal(res_pos.data, expected.data) + + def test_astype(): descr = [('v', int, 3), ('x', [('y', float)])] x = array([ |
