summaryrefslogtreecommitdiff
path: root/numpy/ma
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-04-07 00:01:50 +0100
committerEric Wieser <wieser.eric@gmail.com>2017-05-05 22:27:26 +0100
commit0a8ee4c52f5cecae999904f98a8a30ef81d52f7c (patch)
treef04aac0e9b05c894e6055df665c07db53207071c /numpy/ma
parentb7d30978eaa6c36701958afa19c09f2a0b31670d (diff)
downloadnumpy-0a8ee4c52f5cecae999904f98a8a30ef81d52f7c.tar.gz
DEP: deprecate calling ma.argsort without an axis
Only deprecated when this would be ambiguous. Approaches #8701
Diffstat (limited to 'numpy/ma')
-rw-r--r--numpy/ma/core.py50
-rw-r--r--numpy/ma/tests/test_deprecations.py41
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()