summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/add_newdocs.py28
-rw-r--r--numpy/core/memmap.py4
-rw-r--r--numpy/core/src/arraymethods.c36
-rw-r--r--numpy/core/src/arrayobject.c32
-rw-r--r--numpy/core/src/multiarraymodule.c9
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);