diff options
-rw-r--r-- | numpy/add_newdocs.py | 28 | ||||
-rw-r--r-- | numpy/core/memmap.py | 4 | ||||
-rw-r--r-- | numpy/core/src/arraymethods.c | 36 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 32 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 9 |
5 files changed, 81 insertions, 28 deletions
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index 9cd1c89a5..58940f007 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -648,13 +648,19 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin', add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort', - """a.argsort(axis=-1, kind='quicksort') -> indices that sort a along axis. + """a.argsort(axis=-1, kind='quicksort', order=None) -> indices + + Return array of indices that sort a along the given axis. Keyword arguments: - axis -- axis to be indirectly sorted (default -1) - kind -- sorting algorithm (default 'quicksort') - Possible values: 'quicksort', 'mergesort', or 'heapsort' + axis -- axis to be indirectly sorted (default -1) + kind -- sorting algorithm (default 'quicksort') + Possible values: 'quicksort', 'mergesort', or 'heapsort' + order -- If a has fields defined, then the order keyword can be the + field name to sort on or a list (or tuple) of field names + to indicate the order that fields should be used to define + the sort. Returns: array of indices that sort a along the specified axis. @@ -1017,13 +1023,19 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags', add_newdoc('numpy.core.multiarray', 'ndarray', ('sort', - """a.sort(axis=-1, kind='quicksort') -> None. Sort a along the given axis. + """a.sort(axis=-1, kind='quicksort', order=None) -> None. + + Sort a along the given axis. Keyword arguments: - axis -- axis to be sorted (default -1) - kind -- sorting algorithm (default 'quicksort') - Possible values: 'quicksort', 'mergesort', or 'heapsort'. + axis -- axis to be sorted (default -1) + kind -- sorting algorithm (default 'quicksort') + Possible values: 'quicksort', 'mergesort', or 'heapsort'. + order -- If a has fields defined, then the order keyword can be the + field name to sort on or a list (or tuple) of field names + to indicate the order that fields should be used to define + the sort. Returns: None. diff --git a/numpy/core/memmap.py b/numpy/core/memmap.py index 83e9de1ef..d253dabb7 100644 --- a/numpy/core/memmap.py +++ b/numpy/core/memmap.py @@ -17,7 +17,7 @@ mode_equivalents = { class memmap(ndarray): __array_priority__ = -100.0 def __new__(subtype, name, dtype=uint8, mode='r+', offset=0, - shape=None, order=0): + shape=None, order='C'): try: mode = mode_equivalents[mode] except KeyError: @@ -50,7 +50,7 @@ class memmap(ndarray): for k in shape: size *= k - bytes = offset + size*_dbytes + bytes = long(offset + size*_dbytes) if mode == 'w+' or (mode == 'r+' and flen < bytes): fid.seek(bytes-1,0) diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index b48c0c02b..d33fbc70e 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -862,12 +862,13 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds) &order)) return NULL; + if (order == Py_None) order = NULL; if (order != NULL) { PyObject *new_name; saved = self->descr; if (saved->names == NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify " \ - "order with no fields."); + "order when the array has no fields."); return NULL; } new_name = PyObject_CallMethod(_numpy_internal, "_newnames", @@ -893,13 +894,38 @@ array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=-1; PyArray_SORTKIND which=PyArray_QUICKSORT; - static char *kwlist[] = {"axis", "kind", NULL}; + PyObject *order=NULL, *res; + PyArray_Descr *newd, *saved=NULL; + static char *kwlist[] = {"axis", "kind", "order", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO&", kwlist, &axis, - PyArray_SortkindConverter, &which)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO&O", kwlist, &axis, + PyArray_SortkindConverter, &which, + &order)) return NULL; - return _ARET(PyArray_ArgSort(self, axis, which)); + if (order == Py_None) order = NULL; + if (order != NULL) { + PyObject *new_name; + saved = self->descr; + if (saved->names == NULL) { + PyErr_SetString(PyExc_ValueError, "Cannot specify " \ + "order when the array has no fields."); + return NULL; + } + new_name = PyObject_CallMethod(_numpy_internal, "_newnames", + "OO", saved, order); + if (new_name == NULL) return NULL; + newd = PyArray_DescrNew(saved); + newd->names = new_name; + self->descr = newd; + } + + res = PyArray_ArgSort(self, axis, which); + if (order != NULL) { + Py_XDECREF(self->descr); + self->descr = saved; + } + return _ARET(res); } static PyObject * diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 0485e5ad3..ac85fcd23 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -2280,10 +2280,10 @@ parse_index(PyArrayObject *self, PyObject *op, } static void -_swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret) +_swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getmap) { PyObject *new; - int n1, n2, n3, val; + int n1, n2, n3, val, bnd; int i; PyArray_Dims permute; intp d[MAX_DIMS]; @@ -2308,24 +2308,38 @@ _swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret) if (new == NULL) return; } - /* tuple for transpose is - (n1,..,n1+n2-1,0,..,n1-1,n1+n2,...,n3-1) + /* Setting and getting need to have different permutations. + On the get we are permuting the returned object, but on + setting we are permuting the object-to-be-set. + The set permutation is the inverse of the get permutation. + */ + + /* For getting the array the tuple for transpose is + (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1) n1 is the number of dimensions of the broadcasted index array n2 is the number of dimensions skipped at the - start + start n3 is the number of dimensions of the result */ + + /* For setting the array the tuple for transpose is + (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1) + */ n1 = mit->iters[0]->nd_m1 + 1; n2 = mit->iteraxes[0]; n3 = mit->nd; - val = n1; + + bnd = (getmap ? n1 : n2); /* use n1 as the boundary if getting + but n2 if setting */ + + val = bnd; i = 0; while(val < n1+n2) permute.ptr[i++] = val++; val = 0; - while(val < n1) + while(val < bnd) permute.ptr[i++] = val++; val = n1+n2; while(val < n3) @@ -2395,7 +2409,7 @@ PyArray_GetMap(PyArrayMapIterObject *mit) /* check for consecutive axes */ if ((mit->subspace != NULL) && (mit->consec)) { if (mit->iteraxes[0] > 0) { /* then we need to swap */ - _swap_axes(mit, &ret); + _swap_axes(mit, &ret, 1); } } return (PyObject *)ret; @@ -2421,7 +2435,7 @@ PyArray_SetMap(PyArrayMapIterObject *mit, PyObject *op) if ((mit->subspace != NULL) && (mit->consec)) { if (mit->iteraxes[0] > 0) { /* then we need to swap */ - _swap_axes(mit, (PyArrayObject **)&arr); + _swap_axes(mit, (PyArrayObject **)&arr, 0); if (arr == NULL) return -1; } } diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index 037283615..88b063888 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -2181,7 +2181,8 @@ _new_sort(PyArrayObject *op, int axis, NPY_SORTKIND which) swap = !PyArray_ISNOTSWAPPED(op); if (it == NULL) return -1; - BEGIN_THREADS + NPY_BEGIN_THREADS_DESCR(op->descr) + sort = op->descr->f->sort[which]; size = it->size; N = op->dimensions[axis]; @@ -2216,7 +2217,7 @@ _new_sort(PyArrayObject *op, int axis, NPY_SORTKIND which) } } - END_THREADS + NPY_END_THREADS_DESCR(op->descr) Py_DECREF(it); return 0; @@ -2253,7 +2254,7 @@ _new_argsort(PyArrayObject *op, int axis, NPY_SORTKIND which) swap = !PyArray_ISNOTSWAPPED(op); - BEGIN_THREADS + NPY_BEGIN_THREADS_DESCR(op->descr) argsort = op->descr->f->argsort[which]; size = it->size; @@ -2299,7 +2300,7 @@ _new_argsort(PyArrayObject *op, int axis, NPY_SORTKIND which) } } - END_THREADS + NPY_END_THREADS_DESCR(op->descr) Py_DECREF(it); Py_DECREF(rit); |