5

I have a memoryview on a numpy array and want to copy the content of another numpy array into it by using this memoryview:

import numpy as np
cimport numpy as np

cdef double[:,::1] test = np.array([[0,1],[2,3]], dtype=np.double)

test[...] = np.array([[4,5],[6,7]], dtype=np.double)

But why is this not possible? It keeps me telling

TypeError: only length-1 arrays can be converted to Python scalars Blockquote

It works fine if I copy from a memoryview to a memoryview, or from a numpy array to a numpy array, but how to copy from a numpy array to a memoryview?

4
  • But you can copy from a memoryview on the 2nd array, right? Commented May 23, 2015 at 17:53
  • Yes, but this is very uncomfortable, especially if the operations don't occur at top indentation level. This means: create a cdef double[:,::1] buffer at top indent level, copy in a next step the np.ndarray result into my buffer memoryview and finally from there to my destination memoryview. Commented May 23, 2015 at 18:30
  • 1
    When you link a memoryview to an array you don't copy in. You just define a way of using the array data buffer. The goal in cython is to make operations clear enough to create efficient C code. Programmer 'comfort' (in the usual Python sense) is not a priority. Commented May 23, 2015 at 18:51
  • possible duplicate of Assigning numpy data in cython to a view Commented May 23, 2015 at 19:00

1 Answer 1

4

These assignments work:

cdef double[:,::1] test2d = np.array([[0,1],[2,3],[4,5]], dtype=np.double)
cdef double[:,::1] temp = np.array([[4,5],[6,7]], dtype=np.double)
test2d[...] = 4
test2d[:,1] = np.array([5],dtype=np.double)
test2d[1:,:] = temp
print np.asarray(test2d)

displaying

[[ 4.  5.]
 [ 4.  5.]
 [ 6.  7.]]

I've added an answer at https://stackoverflow.com/a/30418422/901925 that uses this memoryview 'buffer' approach in a indented context.

cpdef int testfunc1c(np.ndarray[np.float_t, ndim=2] A,
                    double [:,:] BView) except -1:
    cdef double[:,:] CView
    if np.isnan(A).any():
        return -1
    else:
        CView = la.inv(A)
        BView[...] = CView
        return 1

It doesn't perform the copy-less buffer assignment that the other poster wanted, but it is still an efficient memoryview copy.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.