diff options
-rw-r--r-- | doc/source/reference/c-api.array.rst | 5 | ||||
-rw-r--r-- | doc/source/reference/c-api.types-and-structures.rst | 5 | ||||
-rw-r--r-- | numpy/add_newdocs.py | 2 | ||||
-rw-r--r-- | numpy/core/fromnumeric.py | 11 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarraytypes.h | 5 | ||||
-rw-r--r-- | numpy/core/include/numpy/old_defines.h | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/conversion_utils.c | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarray/item_selection.c | 2 | ||||
-rw-r--r-- | numpy/ma/core.py | 4 |
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 |