summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/reference/c-api.array.rst5
-rw-r--r--doc/source/reference/c-api.types-and-structures.rst5
-rw-r--r--numpy/add_newdocs.py2
-rw-r--r--numpy/core/fromnumeric.py11
-rw-r--r--numpy/core/include/numpy/ndarraytypes.h5
-rw-r--r--numpy/core/include/numpy/old_defines.h1
-rw-r--r--numpy/core/src/multiarray/conversion_utils.c3
-rw-r--r--numpy/core/src/multiarray/item_selection.c2
-rw-r--r--numpy/ma/core.py4
9 files changed, 24 insertions, 14 deletions
diff --git a/doc/source/reference/c-api.array.rst b/doc/source/reference/c-api.array.rst
index ad7c725a8..3d0a9e8b8 100644
--- a/doc/source/reference/c-api.array.rst
+++ b/doc/source/reference/c-api.array.rst
@@ -2979,7 +2979,8 @@ to.
Convert Python strings into one of :c:data:`NPY_QUICKSORT` (starts
with 'q' or 'Q') , :c:data:`NPY_HEAPSORT` (starts with 'h' or 'H'),
- or :c:data:`NPY_MERGESORT` (starts with 'm' or 'M').
+ :c:data:`NPY_MERGESORT` (starts with 'm' or 'M'), or :c:data:`NPY_STABLESORT`
+ (starts with 's' or 'S').
.. c:function:: int PyArray_SearchsideConverter( \
PyObject* obj, NPY_SEARCHSIDE* side)
@@ -3515,7 +3516,7 @@ Enumerated Types
A special variable-type which can take on the values :c:data:`NPY_{KIND}`
where ``{KIND}`` is
- **QUICKSORT**, **HEAPSORT**, **MERGESORT**
+ **QUICKSORT**, **HEAPSORT**, **MERGESORT**, **STABLESORT**
.. c:var:: NPY_NSORTS
diff --git a/doc/source/reference/c-api.types-and-structures.rst b/doc/source/reference/c-api.types-and-structures.rst
index dcebd1ede..9fb6eb58c 100644
--- a/doc/source/reference/c-api.types-and-structures.rst
+++ b/doc/source/reference/c-api.types-and-structures.rst
@@ -551,8 +551,9 @@ PyArrayDescr_Type
An array of function pointers to a particular sorting
algorithms. A particular sorting algorithm is obtained using a
key (so far :c:data:`NPY_QUICKSORT`, :c:data:`NPY_HEAPSORT`,
- and :c:data:`NPY_MERGESORT` are defined). These sorts are done
- in-place assuming contiguous and aligned data.
+ :c:data:`NPY_MERGESORT`, and :c:data:`NPY_STABLESORT` are
+ defined). These sorts are done in-place assuming contiguous
+ and aligned data.
.. c:member:: int argsort( \
void* start, npy_intp* result, npy_intp length, void *arr)
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index 316b38e77..0a7b2b13d 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -4494,7 +4494,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
axis : int, optional
Axis along which to sort. Default is -1, which means sort along the
last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index 10256c3c0..ddf3314cf 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -764,7 +764,7 @@ def sort(a, axis=-1, kind='quicksort', order=None):
axis : int or None, optional
Axis along which to sort. If None, the array is flattened before
sorting. The default is -1, which sorts along the last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
@@ -797,9 +797,10 @@ def sort(a, axis=-1, kind='quicksort', order=None):
=========== ======= ============= ============ =======
kind speed worst case work space stable
=========== ======= ============= ============ =======
- 'quicksort' 1 O(n^2) 0 no
- 'mergesort' 2 O(n*log(n)) ~n/2 yes
- 'heapsort' 3 O(n*log(n)) 0 no
+ 'quicksort' 1 O(n^2) 0 no
+ 'mergesort' 2 O(n*log(n)) ~n/2 yes
+ 'stable' 2 O(n*log(n)) ~n/2 yes
+ 'heapsort' 3 O(n*log(n)) 0 no
=========== ======= ============= ============ =======
All the sort algorithms make temporary copies of the data when
@@ -886,7 +887,7 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
axis : int or None, optional
Axis along which to sort. The default is -1 (the last axis). If None,
the flattened array is used.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm.
order : str or list of str, optional
When `a` is an array with fields defined, this argument specifies
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index cf73cecea..5febf0c56 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -159,9 +159,10 @@ enum NPY_TYPECHAR {
typedef enum {
NPY_QUICKSORT=0,
NPY_HEAPSORT=1,
- NPY_MERGESORT=2
+ NPY_MERGESORT=2,
+ NPY_STABLESORT=3
} NPY_SORTKIND;
-#define NPY_NSORTS (NPY_MERGESORT + 1)
+#define NPY_NSORTS (NPY_STABLESORT + 1)
typedef enum {
diff --git a/numpy/core/include/numpy/old_defines.h b/numpy/core/include/numpy/old_defines.h
index abf81595a..6d626aa2a 100644
--- a/numpy/core/include/numpy/old_defines.h
+++ b/numpy/core/include/numpy/old_defines.h
@@ -134,6 +134,7 @@
#define PyArray_QUICKSORT NPY_QUICKSORT
#define PyArray_HEAPSORT NPY_HEAPSORT
#define PyArray_MERGESORT NPY_MERGESORT
+#define PyArray_STABLESORT NPY_STABLESORT
#define PyArray_SORTKIND NPY_SORTKIND
#define PyArray_NSORTS NPY_NSORTS
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index b39834266..bf60fba7f 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -419,6 +419,9 @@ PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
else if (str[0] == 'm' || str[0] == 'M') {
*sortkind = NPY_MERGESORT;
}
+ else if (str[0] == 's' || str[0] == 'S') {
+ *sortkind = NPY_STABLESORT;
+ }
else {
PyErr_Format(PyExc_ValueError,
"%s is an unrecognized kind of sort",
diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c
index eb9ef5915..0ee6c8184 100644
--- a/numpy/core/src/multiarray/item_selection.c
+++ b/numpy/core/src/multiarray/item_selection.c
@@ -1130,6 +1130,7 @@ PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
case NPY_HEAPSORT:
sort = npy_heapsort;
break;
+ case NPY_STABLESORT:
case NPY_MERGESORT:
sort = npy_mergesort;
break;
@@ -1281,6 +1282,7 @@ PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
case NPY_HEAPSORT:
argsort = npy_aheapsort;
break;
+ case NPY_STABLESORT:
case NPY_MERGESORT:
argsort = npy_amergesort;
break;
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 5f53dfdae..91cf8ed0f 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -5317,7 +5317,7 @@ class MaskedArray(ndarray):
originally intended.
Until then, the axis should be given explicitly when
``arr.ndim > 1``, to avoid a FutureWarning.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm.
order : list, optional
When `a` is an array with fields defined, this argument specifies
@@ -5468,7 +5468,7 @@ class MaskedArray(ndarray):
axis : int, optional
Axis along which to sort. If None, the array is flattened before
sorting. The default is -1, which sorts along the last axis.
- kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
Sorting algorithm. Default is 'quicksort'.
order : list, optional
When `a` is a structured array, this argument specifies which fields