Using Cython, I try to do this:
cpdef myFun(double[:] array):
cdef int[:] sortIndices = np.argsort(array, kind='mergesort')
array = array[sortIndices]
The compiler complains:
Invalid index for memoryview specified, type int[:]
How do I index this memoryview using an integer array of some sort? Are only slices allowed? I could easily use 'array'-based indexing with the old NumPy array buffer support. (I just adapted my code to use memoryviews to see if it would improve performance, but it actually breaks...)
I'm afraid it is impossible to use a typed memory view as indices the way numpy can use int-arrays.
Cython's documentations states that
"Similar" means it is the same for integers, slices (
:), ellipsis (...) andNone( corresponds tonumpy.newaxis('None')) but not for integer-arrays or boolean-arrays, which can be used as indices in numpy.The Cython-code responsible for generating the access to typed memory views is
generate_buffer_slice_code, and all you have to know is in the doc-string:So
arrayis neither a SliceNode (i.e.:,...or e.g.0:33), norNonenor can it be coerced toPy_ssize_tand thus cannot be handled by Cython as it is.My first thought was, that it will not be too hard to add the functionality to Cython's typed memory views. But this is probably not that easy to do in a consistent way: the result of the operation must be a new typed memory view (as we cannot change the array at hand in-place - the resulting array could have completely different dimensions) - but which type should be the underlying buffer? It is easier in the numpy-world, where everything is a numpy array but the underlying buffer of typed memory view could be numpy-array, an
array.array, a c-array on the stack and so on.Your best option right now is probably to roll out this reordering per hand (so you can explicitly choose the type of the underlying buffer) and replace the broken code through it or to fall back to numpy functionality for this operation as shown in @DavidWs answer.