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?

Assem
  • 11,574
  • 5
  • 59
  • 97
mneuner
  • 433
  • 5
  • 25
  • But you can copy from a memoryview on the 2nd array, right? – hpaulj May 23 '15 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. – mneuner May 23 '15 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. – hpaulj May 23 '15 at 18:51
  • possible duplicate of [Assigning numpy data in cython to a view](http://stackoverflow.com/questions/23827902/assigning-numpy-data-in-cython-to-a-view) – YXD May 23 '15 at 19:00

1 Answers1

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.

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353