From 6d4a6fc870902e5a6ee0f7fb76d8638475370694 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 09:18:21 +0300 Subject: [PATCH 1/6] Revert "BUG: fix ma.minimum.reduce with axis keyword" This reverts commit b8c6d09208ecb7f0d83a8b06ab9e15e720f03730. --- numpy/ma/core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index eef9de71289f..8e7ac9c4ba59 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -6875,8 +6875,6 @@ def reduce(self, target, axis=np._NoValue, **kwargs): if m is nomask: t = self.f.reduce(target.view(np.ndarray), **kwargs) - if isinstance(t, ndarray): - t = MaskedArray(t, mask=nomask) else: target = target.filled( self.fill_value_func(target)).view(type(target)) From acaf2556ba23d73ec2e855d1f5fdd05166e5b5a4 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 09:19:41 +0300 Subject: [PATCH 2/6] Revert "nomask in nomask out" from 21977 This reverts commit db1a98bf194771a677dbc0c2e06bc47f4a9947a8. --- 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 8e7ac9c4ba59..7f17d4adfff1 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -5428,7 +5428,7 @@ def mean(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): result = self.view(np.ndarray).mean(axis=axis, dtype=dtype, **kwargs) if isinstance(result, np.ndarray): - result = MaskedArray(result, mask=nomask) + result = MaskedArray(result, mask=False) else: is_float16_result = False if dtype is None: @@ -5514,7 +5514,7 @@ def var(self, axis=None, dtype=None, out=None, ddof=0, ret = self.view(np.ndarray).var(axis=axis, dtype=dtype, ddof=ddof, **kwargs) if isinstance(ret, np.ndarray): - ret = MaskedArray(ret, mask=nomask) + ret = MaskedArray(ret, mask=False) if out is not None: out.flat = ret if isinstance(out, MaskedArray): From 57d9f0ac15932aabe6c80788c3f9c1147a0acc88 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 09:20:56 +0300 Subject: [PATCH 3/6] Revert "DOC: Adding improvement note for MaskedArray ufunc" This reverts commit fe8b171965d23fc79bd9fc80838debc588e4f376. --- doc/release/upcoming_changes/16022.improvement.rst | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 doc/release/upcoming_changes/16022.improvement.rst diff --git a/doc/release/upcoming_changes/16022.improvement.rst b/doc/release/upcoming_changes/16022.improvement.rst deleted file mode 100644 index 0616163b9937..000000000000 --- a/doc/release/upcoming_changes/16022.improvement.rst +++ /dev/null @@ -1,9 +0,0 @@ -MaskedArray gains a ``__array_ufunc__`` method to better handle ufuncs ----------------------------------------------------------------------- -The MaskedArray class now has an implementation of `__array_ufunc__` that -handles deferrals to the desired implementations of the ufunc. If a masked -implementation of a ufunc exists, that implementation will take priority. -This means that code called with MaskedArray ma as ``np.ufunc(ma)`` will -behave the same as ``np.ma.ufunc(ma)``. Additionally, adding this helps with -dispatching to subclasses and preserving the proper types when another -implementation should take priority. From 3321bc59ca5e47a8d8677fa4d1a9af37d570a835 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 09:23:32 +0300 Subject: [PATCH 4/6] Revert "ENH: Adding __array_ufunc__ capability to MaskedArrays." This reverts commit 8cd6f4ca00b6e0da3833fc267d50067b2ddbc069. --- numpy/lib/tests/test_function_base.py | 2 +- numpy/ma/core.py | 220 +++++--------------------- numpy/ma/extras.py | 17 +- numpy/ma/tests/test_core.py | 4 +- 4 files changed, 48 insertions(+), 195 deletions(-) diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 1c3c32bdd233..8457551ca81e 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -780,7 +780,7 @@ def test_subclass(self): mask=[[False, False], [True, False], [False, True], [True, True], [False, False]]) out = diff(x) - assert_array_equal(out.data, [[1], [4], [6], [8], [1]]) + assert_array_equal(out.data, [[1], [1], [1], [1], [1]]) assert_array_equal(out.mask, [[False], [True], [True], [True], [False]]) assert_(type(out) is type(x)) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 7f17d4adfff1..93eb74be31a8 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -22,7 +22,6 @@ # pylint: disable-msg=E1002 import builtins import inspect -from numbers import Number import operator import warnings import textwrap @@ -59,10 +58,10 @@ 'frombuffer', 'fromflex', 'fromfunction', 'getdata', 'getmask', 'getmaskarray', 'greater', 'greater_equal', 'harden_mask', 'hypot', 'identity', 'ids', 'indices', 'inner', 'innerproduct', 'isMA', - 'isMaskedArray', 'is_mask', 'is_masked', 'isarray', 'isfinite', - 'isinf', 'isnan', 'left_shift', 'less', 'less_equal', 'log', 'log10', - 'log2', 'logical_and', 'logical_not', 'logical_or', 'logical_xor', - 'make_mask', 'make_mask_descr', 'make_mask_none', 'mask_or', 'masked', + 'isMaskedArray', 'is_mask', 'is_masked', 'isarray', 'left_shift', + 'less', 'less_equal', 'log', 'log10', 'log2', + 'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'make_mask', + 'make_mask_descr', 'make_mask_none', 'mask_or', 'masked', 'masked_array', 'masked_equal', 'masked_greater', 'masked_greater_equal', 'masked_inside', 'masked_invalid', 'masked_less', 'masked_less_equal', 'masked_not_equal', @@ -926,12 +925,6 @@ def __call__(self, a, *args, **kwargs): """ d = getdata(a) - if 'out' in kwargs: - # Need to drop the mask from the output array when being called - kwargs['out'] = getdata(kwargs['out']) - args = [getdata(arg) if isinstance(arg, MaskedArray) else arg - for arg in args] - # Deal with domain if self.domain is not None: # Case 1.1. : Domained function @@ -1055,7 +1048,7 @@ def __call__(self, a, b, *args, **kwargs): masked_result._update_from(b) return masked_result - def reduce(self, target, axis=0, dtype=None, **kwargs): + def reduce(self, target, axis=0, dtype=None): """ Reduce `target` along the given `axis`. @@ -1190,10 +1183,6 @@ def __call__(self, a, b, *args, **kwargs): # Transforms to a (subclass of) MaskedArray masked_result = result.view(get_masked_subclass(a, b)) - # If the original masks were scalar or nomask, don't expand the result - # which comes from the isfinite initialization above - if getmask(a).shape + getmask(b).shape == (): - m = _shrink_mask(m) masked_result._mask = m if isinstance(a, MaskedArray): masked_result._update_from(a) @@ -1220,9 +1209,6 @@ def __call__(self, a, b, *args, **kwargs): ceil = _MaskedUnaryOperation(umath.ceil) around = _MaskedUnaryOperation(np.round_) logical_not = _MaskedUnaryOperation(umath.logical_not) -isinf = _MaskedUnaryOperation(umath.isinf) -isnan = _MaskedUnaryOperation(umath.isnan) -isfinite = _MaskedUnaryOperation(umath.isfinite) # Domained unary ufuncs sqrt = _MaskedUnaryOperation(umath.sqrt, 0.0, @@ -3095,7 +3081,7 @@ def __array_wrap__(self, obj, context=None): 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, [getmask(arg) for arg in input_args]) + 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: @@ -3123,6 +3109,7 @@ def __array_wrap__(self, obj, context=None): else: # Don't modify inplace, we risk back-propagation m = (m | d) + # Make sure the mask has the proper size if result is not self and result.shape == () and m: return masked @@ -3132,85 +3119,6 @@ def __array_wrap__(self, obj, context=None): return result - def __array_ufunc__(self, np_ufunc, method, *inputs, **kwargs): - """ - MaskedArray capability for ufuncs - - Handle masked versions of ufuncs if they are implemented within - the MaskedArray module. If the masked ufunc is not implemented, - this falls back to the standard numpy ndarray ufunc, which we - then call with the ndarray view of the input data. - - """ - # Output can be specified as arguments or as keyword arguments - outputs = kwargs.pop('out', ()) - if not isinstance(outputs, tuple): - outputs = (outputs,) - outputs += inputs[np_ufunc.nin:] - args = inputs[:np_ufunc.nin] - - # Determine what class types we are compatible with and return - # NotImplemented if we don't know how to handle them - for arg in args + outputs: - if not isinstance(arg, (ndarray, np.bool_, Number, list, str)): - return NotImplemented - - # Get the equivalent masked version of the numpy function - # if it is in the module level functions - ma_ufunc = np.ma.__dict__.get(np_ufunc.__name__, np_ufunc) - if ma_ufunc is np_ufunc: - # We didn't have a Masked version of the ufunc, so we need to - # call the ndarray version with the data from the objects and - # prevent infinite recursion. - - # Make ndarray views of the input arguments - args = [getdata(input) if isinstance(input, MaskedArray) - else input for input in args] - else: - # The masked power function doesn't support extra args - if np_ufunc.__name__ in ('power'): - kwargs = {} - - results = getattr(ma_ufunc, method)(*args, **kwargs) - if results is NotImplemented: - return NotImplemented - if method == 'at': - return - if np_ufunc.nout == 1: - results = (results,) - if outputs == (): - outputs = (None,) * np_ufunc.nout - - returns = [] - for i, result in enumerate(results): - output = outputs[i] - - # Reapply the mask - if isinstance(result, ndarray) and result is not masked: - # Need to copy over all of the data and mask from results - # to the original object requested with out - if output is not None: - if isinstance(output, MaskedArray): - output._update_from(result) - if isinstance(result, MaskedArray): - output.data[:] = result._data - output._mask = result._mask - else: - output.data[:] = result - else: - output[:] = result - - result = output - - elif output is not None: - # An out value was requested, but the result is a scalar - output[()] = result - result = output - - returns.append(result) - - return returns[0] if np_ufunc.nout == 1 else returns - def view(self, dtype=None, type=None, fill_value=None): """ Return a view of the MaskedArray data. @@ -3384,7 +3292,7 @@ def _scalar_heuristic(arr, elem): return dout else: # Force dout to MA - dout = MaskedArray(dout) + dout = dout.view(type(self)) # Inherit attributes from self dout._update_from(self) # Check the fill_value @@ -3946,23 +3854,6 @@ def filled(self, fill_value=None): result = self._data return result - def clip(self, a_min, a_max, out=None, **kwargs): - """docstring inherited - np.clip.__doc__ - - TODO: Should we ignore the clip where the data is masked? - It is currently in line with the old numpy version - """ - result = self.data.clip(a_min, a_max, **kwargs).view(MaskedArray) - if out is not None: - # Just copy the data and mask - out.data[:] = getdata(result) - out._mask = self._mask - return out - result._update_from(self) - result._mask = self._mask - return result - def compressed(self): """ Return all the non-masked data as a 1-D array. @@ -4056,15 +3947,10 @@ def compress(self, condition, axis=None, out=None): # values. condition = np.asarray(condition) - _new = _data.compress(condition, axis=axis).view(type(self)) + _new = _data.compress(condition, axis=axis, out=out).view(type(self)) _new._update_from(self) if _mask is not nomask: _new._mask = _mask.compress(condition, axis=axis) - if out is not None: - out._update_from(self) - out.data[:] = _new.data - out._mask = _new.mask - return out return _new def _insert_masked_print(self): @@ -4314,7 +4200,7 @@ def __add__(self, other): """ if self._delegate_binop(other): return NotImplemented - return np.add(self, other) + return add(self, other) def __radd__(self, other): """ @@ -4323,7 +4209,7 @@ def __radd__(self, other): """ # In analogy with __rsub__ and __rdiv__, use original order: # we get here from `other + self`. - return np.add(other, self) + return add(other, self) def __sub__(self, other): """ @@ -4332,20 +4218,20 @@ def __sub__(self, other): """ if self._delegate_binop(other): return NotImplemented - return np.subtract(self, other) + return subtract(self, other) def __rsub__(self, other): """ Subtract self from other, and return a new masked array. """ - return np.subtract(other, self) + return subtract(other, self) def __mul__(self, other): "Multiply self by other, and return a new masked array." if self._delegate_binop(other): return NotImplemented - return np.multiply(self, other) + return multiply(self, other) def __rmul__(self, other): """ @@ -4354,7 +4240,7 @@ def __rmul__(self, other): """ # In analogy with __rsub__ and __rdiv__, use original order: # we get here from `other * self`. - return np.multiply(other, self) + return multiply(other, self) def __div__(self, other): """ @@ -4363,7 +4249,7 @@ def __div__(self, other): """ if self._delegate_binop(other): return NotImplemented - return np.divide(self, other) + return divide(self, other) def __truediv__(self, other): """ @@ -4372,14 +4258,14 @@ def __truediv__(self, other): """ if self._delegate_binop(other): return NotImplemented - return np.true_divide(self, other) + return true_divide(self, other) def __rtruediv__(self, other): """ Divide self into other, and return a new masked array. """ - return np.true_divide(other, self) + return true_divide(other, self) def __floordiv__(self, other): """ @@ -4388,14 +4274,14 @@ def __floordiv__(self, other): """ if self._delegate_binop(other): return NotImplemented - return np.floor_divide(self, other) + return floor_divide(self, other) def __rfloordiv__(self, other): """ Divide self into other, and return a new masked array. """ - return np.floor_divide(other, self) + return floor_divide(other, self) def __pow__(self, other): """ @@ -5172,8 +5058,8 @@ def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): #!!!: implement out + test! m = self._mask if m is nomask: - result = self.view(np.ndarray).trace(offset=offset, axis1=axis1, - axis2=axis2, out=out) + result = super().trace(offset=offset, axis1=axis1, axis2=axis2, + out=out) return result.astype(dtype) else: D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2) @@ -5273,9 +5159,7 @@ def sum(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): result = masked return result # Explicit output - - self.filled(0).sum(axis, dtype=dtype, out=out.view(np.ndarray), - **kwargs) + result = self.filled(0).sum(axis, dtype=dtype, out=out, **kwargs) if isinstance(out, MaskedArray): outmask = getmask(out) if outmask is nomask: @@ -5425,10 +5309,7 @@ def mean(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): """ kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} if self._mask is nomask: - result = self.view(np.ndarray).mean(axis=axis, - dtype=dtype, **kwargs) - if isinstance(result, np.ndarray): - result = MaskedArray(result, mask=False) + result = super().mean(axis=axis, dtype=dtype, **kwargs)[()] else: is_float16_result = False if dtype is None: @@ -5511,12 +5392,9 @@ def var(self, axis=None, dtype=None, out=None, ddof=0, # Easy case: nomask, business as usual if self._mask is nomask: - ret = self.view(np.ndarray).var(axis=axis, dtype=dtype, - ddof=ddof, **kwargs) - if isinstance(ret, np.ndarray): - ret = MaskedArray(ret, mask=False) + ret = super().var(axis=axis, dtype=dtype, out=out, ddof=ddof, + **kwargs)[()] if out is not None: - out.flat = ret if isinstance(out, MaskedArray): out.__setmask__(nomask) return out @@ -5574,10 +5452,12 @@ def std(self, axis=None, dtype=None, out=None, ddof=0, numpy.std : Equivalent function """ kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + dvar = self.var(axis, dtype, out, ddof, **kwargs) if dvar is not masked: if out is not None: - return np.power(out, 0.5, out=out, casting='unsafe') + np.power(out, 0.5, out=out, casting='unsafe') + return out dvar = sqrt(dvar) return dvar @@ -5592,10 +5472,6 @@ def round(self, decimals=0, out=None): numpy.ndarray.round : corresponding function for ndarrays numpy.around : equivalent function """ - stored_out = None - if isinstance(out, MaskedArray): - stored_out = out - out = getdata(out) result = self._data.round(decimals=decimals, out=out).view(type(self)) if result.ndim > 0: result._mask = self._mask @@ -5606,9 +5482,7 @@ def round(self, decimals=0, out=None): # No explicit output: we're done if out is None: return result - if stored_out is not None: - # We got in a masked array originally, so we need to return one - out = stored_out + if isinstance(out, MaskedArray): out.__setmask__(self._mask) return out @@ -5996,7 +5870,7 @@ def mini(self, axis=None): "`mini` is deprecated; use the `min` method or " "`np.ma.minimum.reduce instead.", DeprecationWarning, stacklevel=2) - return MaskedArray(np.min(self, axis)) + return minimum.reduce(self, axis) def max(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue): """ @@ -6160,13 +6034,13 @@ def partition(self, *args, **kwargs): warnings.warn("Warning: 'partition' will ignore the 'mask' " f"of the {self.__class__.__name__}.", stacklevel=2) - return self.view(np.ndarray).partition(*args, **kwargs) + return super().partition(*args, **kwargs) def argpartition(self, *args, **kwargs): warnings.warn("Warning: 'argpartition' will ignore the 'mask' " f"of the {self.__class__.__name__}.", stacklevel=2) - return self.view(np.ndarray).argpartition(*args, **kwargs) + return super().argpartition(*args, **kwargs) def take(self, indices, axis=None, out=None, mode='raise'): """ @@ -6856,7 +6730,7 @@ def __call__(self, a, b=None): return self.reduce(a) return where(self.compare(a, b), a, b) - def reduce(self, target, axis=np._NoValue, **kwargs): + def reduce(self, target, axis=np._NoValue): "Reduce target along the given axis." target = narray(target, copy=False, subok=True) m = getmask(target) @@ -6871,10 +6745,12 @@ def reduce(self, target, axis=np._NoValue, **kwargs): axis = None if axis is not np._NoValue: - kwargs['axis'] = axis + kwargs = dict(axis=axis) + else: + kwargs = dict() if m is nomask: - t = self.f.reduce(target.view(np.ndarray), **kwargs) + t = self.f.reduce(target, **kwargs) else: target = target.filled( self.fill_value_func(target)).view(type(target)) @@ -8078,23 +7954,6 @@ def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8): """ x = masked_array(a, copy=False) y = masked_array(b, copy=False) - if masked_equal: - # Apply the combined mask right away to avoid comparisons at the - # masked locations (assumed mask is True) - m = mask_or(getmask(x), getmask(y)) - # Expand scalars to the proper dimension for comparison if needed - if shape(x) != shape(y): - if size(x) == 1: - # scalar a - x = masked_array(np.ones(shape=shape(y))*x, mask=m) - elif size(y) == 1: - # scalar b - y = masked_array(np.ones(shape=shape(x))*y, mask=m) - else: - raise ValueError("Cannot compare arrays of different shapes.") - else: - x = masked_array(a, copy=False, mask=m) - y = masked_array(b, copy=False, mask=m) # make sure y is an inexact type to avoid abs(MIN_INT); will cause # casting of x later. @@ -8107,7 +7966,8 @@ def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8): if y.dtype != dtype: y = masked_array(y, dtype=dtype, copy=False) - xinf = filled(np.isinf(x), False) + m = mask_or(getmask(x), getmask(y)) + xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False) # If we have some infs, they should fall at the same place. if not np.all(xinf == filled(np.isinf(y), False)): return False diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py index 9111355055b1..b7ff1adbc2da 100644 --- a/numpy/ma/extras.py +++ b/numpy/ma/extras.py @@ -588,8 +588,8 @@ def average(a, axis=None, weights=None, returned=False, *, >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3], ... returned=True) >>> avg - masked_array(data=[2.66666667, 3.66666667], - mask=False, + masked_array(data=[2.6666666666666665, 3.6666666666666665], + mask=[False, False], fill_value=1e+20) With ``keepdims=True``, the following result has shape (3, 1). @@ -2019,15 +2019,8 @@ def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False): not_m = ~m if w is not None: w = w[not_m] - x = x[not_m] - y = y[not_m] - - # Only pass the ndarray data - if w is not None: - w = w.view(np.ndarray) - x = x.view(np.ndarray) - y = y.view(np.ndarray) - - return np.polyfit(x, y, deg, rcond, full, w, cov) + return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov) + else: + return np.polyfit(x, y, deg, rcond, full, w, cov) polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index c2ba6fd77b3e..4868ff7909a9 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -3220,7 +3220,7 @@ def test_compress(self): assert_equal(b.fill_value, 9999) assert_equal(b, a[condition]) - condition = (a.data < 4.) + condition = (a < 4.) b = a.compress(condition) assert_equal(b._data, [1., 2., 3.]) assert_equal(b._mask, [0, 0, 1]) @@ -5379,7 +5379,7 @@ def test_ufunc_with_out_varied(): 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([1, 22, 33], mask=[1, 0, 0]) + expected = array([11, 22, 33], mask=[1, 0, 0]) out_pos = out.copy() res_pos = np.add(a, b, out_pos) From 20bd00b0bfef5de4046d31a04b84f0a5a4007cdf Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 09:28:42 +0300 Subject: [PATCH 5/6] Revert "BUG: Fix masked median multiple masked arrays (#21999)" This reverts commit 6b8d55e66e532d66e1701ad039b4cda306839b3f. --- numpy/ma/extras.py | 5 +---- numpy/ma/tests/test_extras.py | 19 ------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py index b7ff1adbc2da..d2986012b7ac 100644 --- a/numpy/ma/extras.py +++ b/numpy/ma/extras.py @@ -723,10 +723,7 @@ def median(a, axis=None, out=None, overwrite_input=False, keepdims=False): fill_value=1e+20) """ - - a = np.ma.asarray(a) - - if a.mask is np.ma.nomask: + if not hasattr(a, 'mask'): m = np.median(getdata(a, subok=True), axis=axis, out=out, overwrite_input=overwrite_input, keepdims=keepdims) diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 3637accc39f8..04bf8cfc2284 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -1160,25 +1160,6 @@ def test_object(self): o[2] = np.nan assert_(type(np.ma.median(o.astype(object))), float) - def test_list_of_masked_array(self): - data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) - masked1 = np.ma.masked_where(data1 == 4, data1) - data2 = np.array([[8, 7, 6, 5], [4, 3, 2, 1]]) - masked2 = np.ma.masked_where(data2 == 4, data2) - list = [masked1, masked2] - median_masked_list = np.ma.median(list, axis=0).data - assert_equal(median_masked_list, - np.array([[4.5, 4.5, 4.5, 5], [5, 4.5, 4.5, 4.5]])) - - def test_list_of_masked_array_no_axis(self): - data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) - masked1 = np.ma.masked_where(data1 == 2, data1) - data2 = np.array([[8, 7, 6, 5], [4, 3, 2, 1]]) - masked2 = np.ma.masked_where(data2 == 5, data2) - list = [masked1, masked2] - median_masked_list = np.ma.median(list) - assert_equal(median_masked_list, 4.5) - class TestCov: From a346e6d483483751b95915267b655e06889c9b1a Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 20 Jul 2022 10:33:13 +0300 Subject: [PATCH 6/6] Revert "TST: add a test for ma.minimum.reduce with axis keyword" This reverts commit e2efced9bdfc773f5aca2487f12ab1cb2bd11833. --- numpy/ma/tests/test_core.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index 4868ff7909a9..b056d516907b 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -1235,18 +1235,6 @@ def test_minmax_reduce(self): b = np.maximum.reduce(a) assert_equal(b, 3) - def test_minmax_reduce_axis(self): - # Test np.min/maximum.reduce along an axis for 2D array - import numpy as np - data = [[0, 1, 2, 3, 4, 9], [5, 5, 0, 9, 3, 3]] - mask = [[0, 0, 0, 0, 0, 1], [0, 0, 1, 1, 0, 0]] - a = array(data, mask=mask) - - expected = array([0, 3], mask=False) - result = np.minimum.reduce(a, axis=1) - - assert_array_equal(result, expected) - def test_minmax_funcs_with_output(self): # Tests the min/max functions with explicit outputs mask = np.random.rand(12).round()