[Cython] Can't assign numpy array to memoryview

Dave Hirschfeld dave.hirschfeld at gmail.com
Mon Dec 8 13:22:32 CET 2014


It appears that you can't assign an ndarray to a memoryview slice? Is 
this correct/expected behaviour?

Whilst there are a couple of possible workarounds it would be nice if 
this just worked as it's a slightly surprising deviation from the 
ndarray behaviour.

Broken example:
```
In [3]: %%cython
   ...: cimport cython
   ...: import numpy as np
   ...: cimport numpy as np
   ...: 
   ...: cpdef np.ndarray[np.float64_t, ndim=2] f():
   ...:     cdef np.ndarray[np.float64_t, ndim=2] x = np.ones([3, 4], 
dtype=np.float64)
   ...:     cdef double[:,:] y = np.zeros([3, 4], dtype=np.float64)
   ...:     cdef np.ndarray[np.float64_t, ndim=1] row
   ...:     cdef int idx
   ...:     for idx, row in enumerate(x):
   ...:         y[idx] = row
   ...:     return np.asarray(y)

In [4]: f()
Traceback (most recent call last):

  File "<ipython-input-4-0ec059b9bfe1>", line 1, in <module>
    f()

  File "_cython_magic_5f2586693ddbf044815dae01d800bc0c.pyx", line 5, in 
_cython_magic_5f2586693ddbf044815dae01d800bc0c.f 
(C:\Users\dhirschfeld\.ipython\cython\_cython_magic_5f2586693ddbf044815d
ae01d800bc0c.c:2086)

  File "_cython_magic_5f2586693ddbf044815dae01d800bc0c.pyx", line 11, in 
_cython_magic_5f2586693ddbf044815dae01d800bc0c.f 
(C:\Users\dhirschfeld\.ipython\cython\_cython_magic_5f2586693ddbf044815d
ae01d800bc0c.c:1935)
```

Workarounds - either:
1. Type both lhs and rhs as ndarray
2. Create a 1D memoryview to use as a temporary container and assign 
that to the memoryview slice

```
In [5]: %%cython
   ...: cimport cython
   ...: import numpy as np
   ...: cimport numpy as np
   ...: 
   ...: cpdef np.ndarray[np.float64_t, ndim=2] f():
   ...:     cdef np.ndarray[np.float64_t, ndim=2] x = np.ones([3, 4], 
dtype=np.float64)
   ...:     cdef np.ndarray[np.float64_t, ndim=2] y = np.zeros([3, 4], 
dtype=np.float64)
   ...:     cdef np.ndarray[np.float64_t, ndim=1] row
   ...:     cdef int idx
   ...:     for idx, row in enumerate(x):
   ...:         y[idx] = row
   ...:     return np.asarray(y)

In [6]: f()
Out[6]: 
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])

In [7]: %%cython
   ...: cimport cython
   ...: import numpy as np
   ...: cimport numpy as np
   ...: 
   ...: cpdef np.ndarray[np.float64_t, ndim=2] f():
   ...:     cdef np.ndarray[np.float64_t, ndim=2] x = np.ones([3, 4], 
dtype=np.float64)
   ...:     cdef double[:,:] y = np.zeros([3, 4], dtype=np.float64)
   ...:     cdef np.ndarray[np.float64_t, ndim=1] row
   ...:     cdef double[:] tmp
   ...:     cdef int idx
   ...:     for idx, row in enumerate(x):
   ...:         tmp = row
   ...:         y[idx] = tmp
   ...:     return np.asarray(y)

In [8]: f()
Out[8]: 
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])
```



More information about the cython-devel mailing list