diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2017-05-05 18:11:11 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-05 18:11:11 -0600 |
commit | 6153a705c3bf30992ff5bd064ff0507ac78300e4 (patch) | |
tree | cb327bdd10956d0467a5b86203c22e4dbb24ed55 /numpy/ma | |
parent | 857125603f3cf72e2078ed2effd0f6ce40f0ca28 (diff) | |
parent | 0a8ee4c52f5cecae999904f98a8a30ef81d52f7c (diff) | |
download | numpy-6153a705c3bf30992ff5bd064ff0507ac78300e4.tar.gz |
Merge pull request #8918 from eric-wieser/deprecate-ma-argsort-no-axis
DEP: deprecate calling ma.argsort without an axis
Diffstat (limited to 'numpy/ma')
-rw-r--r-- | numpy/ma/core.py | 50 | ||||
-rw-r--r-- | numpy/ma/tests/test_deprecations.py | 41 |
2 files changed, 87 insertions, 4 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index cb0bfdde2..20cc77bc4 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -93,6 +93,33 @@ nomask = MaskType(0) class MaskedArrayFutureWarning(FutureWarning): pass +def _deprecate_argsort_axis(arr): + """ + Adjust the axis passed to argsort, warning if necessary + + Parameters + ---------- + arr + The array which argsort was called on + + np.ma.argsort has a long-term bug where the default of the axis argument + is wrong (gh-8701), which now must be kept for backwards compatibiity. + Thankfully, this only makes a difference when arrays are 2- or more- + dimensional, so we only need a warning then. + """ + if arr.ndim <= 1: + # no warning needed - but switch to -1 anyway, to avoid surprising + # subclasses, which are more likely to implement scalar axes. + return -1 + else: + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + warnings.warn( + "In the future the default for argsort will be axis=-1, not the " + "current None, to match its documentation and np.argsort. " + "Explicitly pass -1 or None to silence this warning.", + MaskedArrayFutureWarning, stacklevel=3) + return None + def doc_note(initialdoc, note): """ @@ -5285,7 +5312,7 @@ class MaskedArray(ndarray): out.__setmask__(self._mask) return out - def argsort(self, axis=None, kind='quicksort', order=None, + def argsort(self, axis=np._NoValue, kind='quicksort', order=None, endwith=True, fill_value=None): """ Return an ndarray of indices that sort the array along the @@ -5295,8 +5322,15 @@ class MaskedArray(ndarray): Parameters ---------- axis : int, optional - Axis along which to sort. The default is -1 (last axis). - If None, the flattened array is used. + Axis along which to sort. If None, the default, the flattened array + is used. + + .. versionchanged:: 1.13.0 + Previously, the default was documented to be -1, but that was + in error. At some future date, the default will change to -1, as + originally intended. + Until then, the axis should be given explicitly when + ``arr.ndim > 1``, to avoid a FutureWarning. kind : {'quicksort', 'mergesort', 'heapsort'}, optional Sorting algorithm. order : list, optional @@ -5341,6 +5375,10 @@ class MaskedArray(ndarray): """ + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + if axis is np._NoValue: + axis = _deprecate_argsort_axis(self) + if fill_value is None: if endwith: # nan > inf @@ -6560,10 +6598,14 @@ def power(a, b, third=None): argmin = _frommethod('argmin') argmax = _frommethod('argmax') -def argsort(a, axis=None, kind='quicksort', order=None, endwith=True, fill_value=None): +def argsort(a, axis=np._NoValue, kind='quicksort', order=None, endwith=True, fill_value=None): "Function version of the eponymous method." a = np.asanyarray(a) + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + if axis is np._NoValue: + axis = _deprecate_argsort_axis(a) + if isinstance(a, MaskedArray): return a.argsort(axis=axis, kind=kind, order=order, endwith=endwith, fill_value=fill_value) diff --git a/numpy/ma/tests/test_deprecations.py b/numpy/ma/tests/test_deprecations.py new file mode 100644 index 000000000..d66980031 --- /dev/null +++ b/numpy/ma/tests/test_deprecations.py @@ -0,0 +1,41 @@ +"""Test deprecation and future warnings. + +""" +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 + + +class TestArgsort(TestCase): + """ gh-8701 """ + def _test_base(self, argsort, cls): + arr_0d = np.array(1).view(cls) + argsort(arr_0d) + + arr_1d = np.array([1, 2, 3]).view(cls) + argsort(arr_1d) + + # argsort has a bad default for >1d arrays + arr_2d = np.array([[1, 2], [3, 4]]).view(cls) + result = assert_warns( + np.ma.core.MaskedArrayFutureWarning, argsort, arr_2d) + assert_equal(result, argsort(arr_2d, axis=None)) + + # should be no warnings for explictly specifiying it + argsort(arr_2d, axis=None) + argsort(arr_2d, axis=-1) + + def test_function_ndarray(self): + return self._test_base(np.ma.argsort, np.ndarray) + + def test_function_maskedarray(self): + return self._test_base(np.ma.argsort, np.ma.MaskedArray) + + def test_method(self): + return self._test_base(np.ma.MaskedArray.argsort, np.ma.MaskedArray) + + +if __name__ == "__main__": + run_module_suite() |