diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2017-04-13 16:24:35 +0100 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2017-05-06 12:20:59 +0100 |
commit | e1dc37bc0572e280a0e4263d41cd600aaccc8aa5 (patch) | |
tree | cc97f69ca51364c39649bf051f0d8382b3f8d865 | |
parent | b0124491e6b5e2edc96c2af92f4ec8727319f252 (diff) | |
download | numpy-e1dc37bc0572e280a0e4263d41cd600aaccc8aa5.tar.gz |
DEP: inconsistent axis default for np.ma.maximum
This does not match np.maximum, which is confusing because the masked
version has no documentation at all. This uses a similar deprecation approach
to gh-8918, noting that the warning is only needed for arrays of more than one
dimension.
The same remarks apply to `np.ma.minimum`
-rw-r--r-- | doc/release/1.13.0-notes.rst | 7 | ||||
-rw-r--r-- | numpy/ma/core.py | 32 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 2 | ||||
-rw-r--r-- | numpy/ma/tests/test_deprecations.py | 27 |
4 files changed, 51 insertions, 17 deletions
diff --git a/doc/release/1.13.0-notes.rst b/doc/release/1.13.0-notes.rst index 665b9fa97..3deca6a8c 100644 --- a/doc/release/1.13.0-notes.rst +++ b/doc/release/1.13.0-notes.rst @@ -28,9 +28,10 @@ Deprecations * Use of the C-API ``NPY_CHAR`` type number deprecated since version 1.7 will now raise deprecation warnings at runtime. Extensions built with older f2py versions need to be recompiled to remove the warning. -* ``np.ma.argsort`` should be called with an explicit `axis` argument when - applied to arrays with more than 2 dimensions, as the default value of - this argument (``None``) is inconsistent with the rest of numpy (``-1``). +* ``np.ma.argsort``, ``np.ma.minimum.reduce``, and ``np.ma.maximum.reduce`` + should be called with an explicit `axis` argument when applied to arrays with + more than 2 dimensions, as the default value of this argument (``None``) is + inconsistent with the rest of numpy (``-1``, ``0``, and ``0``, respectively). * ``np.ma.MaskedArray.mini`` is deprecated, as it almost duplicates the functionality of ``np.MaskedArray.min``. Exactly equivalent behaviour can be obtained with ``np.ma.minimum.reduce``. diff --git a/numpy/ma/core.py b/numpy/ma/core.py index c3f80ea27..e1da2832e 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -6383,24 +6383,34 @@ class _extrema_operation(object): return self.reduce(a) return where(self.compare(a, b), a, b) - def reduce(self, target, axis=None): + def reduce(self, target, axis=np._NoValue): "Reduce target along the given axis." target = narray(target, copy=False, subok=True) m = getmask(target) - if axis is not None: - kargs = {'axis': axis} + + if axis is np._NoValue and target.ndim > 1: + # 2017-05-06, Numpy 1.13.0: warn on axis default + warnings.warn( + "In the future the default for ma.{0}.reduce will be axis=0, " + "not the current None, to match np.{0}.reduce. " + "Explicitly pass 0 or None to silence this warning.".format( + self.__name__ + ), + MaskedArrayFutureWarning, stacklevel=2) + axis = None + + if axis is not np._NoValue: + kwargs = dict(axis=axis) else: - kargs = {} - target = target.ravel() - if not (m is nomask): - m = m.ravel() + kwargs = dict() + if m is nomask: - t = self.ufunc.reduce(target, **kargs) + t = self.ufunc.reduce(target, **kwargs) else: target = target.filled( self.fill_value_func(target)).view(type(target)) - t = self.ufunc.reduce(target, **kargs) - m = umath.logical_and.reduce(m, **kargs) + t = self.ufunc.reduce(target, **kwargs) + m = umath.logical_and.reduce(m, **kwargs) if hasattr(t, '_mask'): t._mask = m elif m: @@ -6433,7 +6443,6 @@ class _minimum_operation(_extrema_operation): In one argument case, returns the scalar minimum. """ self.ufunc = umath.minimum - self.afunc = amin self.compare = less self.fill_value_func = minimum_fill_value @@ -6447,7 +6456,6 @@ class _maximum_operation(_extrema_operation): In one argument case returns the scalar maximum. """ self.ufunc = umath.maximum - self.afunc = amax self.compare = greater self.fill_value_func = maximum_fill_value diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index f20c9ba52..e72088692 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -1065,7 +1065,7 @@ class TestMaskedArrayArithmetic(TestCase): x = arange(4).reshape(2, 2) x[-1, -1] = masked - assert_equal(maximum.reduce(x), 2) + assert_equal(maximum.reduce(x, axis=None), 2) def test_minimummaximum_func(self): a = np.ones((2, 2)) diff --git a/numpy/ma/tests/test_deprecations.py b/numpy/ma/tests/test_deprecations.py index 6b3c30e04..661e989d8 100644 --- a/numpy/ma/tests/test_deprecations.py +++ b/numpy/ma/tests/test_deprecations.py @@ -6,7 +6,7 @@ from __future__ import division, absolute_import, print_function import numpy as np from numpy.testing import TestCase, run_module_suite, assert_warns from numpy.ma.testutils import assert_equal - +from numpy.ma.core import MaskedArrayFutureWarning class TestArgsort(TestCase): """ gh-8701 """ @@ -44,6 +44,31 @@ class TestMinimumMaximum(TestCase): def test_maximum(self): assert_warns(DeprecationWarning, np.ma.maximum, np.ma.array([1, 2])) + def test_axis_default(self): + # NumPy 1.13, 2017-05-06 + + data1d = np.ma.arange(6) + data2d = data1d.reshape(2, 3) + + ma_min = np.ma.minimum.reduce + ma_max = np.ma.maximum.reduce + + # check that the default axis is still None, but warns on 2d arrays + result = assert_warns(MaskedArrayFutureWarning, ma_max, data2d) + assert_equal(result, ma_max(data2d, axis=None)) + + result = assert_warns(MaskedArrayFutureWarning, ma_min, data2d) + assert_equal(result, ma_min(data2d, axis=None)) + + # no warnings on 1d, as both new and old defaults are equivalent + result = ma_min(data1d) + assert_equal(result, ma_min(data1d, axis=None)) + assert_equal(result, ma_min(data1d, axis=0)) + + result = ma_max(data1d) + assert_equal(result, ma_max(data1d, axis=None)) + assert_equal(result, ma_max(data1d, axis=0)) + if __name__ == "__main__": run_module_suite() |