I am trying to initialize a slice (not not whole) of a memoryview. Suppose that I have memoryview A
as an attribute of a class (Extension Type)
from cython.view cimport array as cvarray
N = 1000
cdef double[:,:,::1] A = cvarray(shape=(2,N,N),itemsize=sizeof(double),format='d')
Now, I am trying to initialize it in a cdef
function. I have no problem initializing the whole memoryview like this
# From elsewhere we have loaded a numpy.ndarray B of size (2,N,N)
A[:,:,:] = B
This is fine when the initializer B
is 3D array (2,N,N)
so that we do not have to slice A
. But now, the problem is here: suppose that I have 2D arrays B1
and B2
of size (N,N), and trying to initialize as
A[0,:,:] = B1
A[1,:,:] = B2
This gives me the following error:
TypeError: only length-1 arrays can be converted to Python scalars
Of course I can copy all data one-by-one from B1
and B2
to A
, but this would not be efficient. This process is in a loop and the size N
is large. B1
and B2
come form loading netcdf files as numpy.ndarray
type.
Also, I am defining A
to be as a memoryview so that somewhere else in the code I can use nogil
functions over accessing A
.
I am wondering if there is an efficient way to initialize the memoryview as above, or at least, somehow play with pointers of B1
and B2
and put them together into an iterable array. Thanks.
I can find two options:
B1
and B2
as a memoryview.You can access the base
attribute of the memoryview to get the cvarray
and index that:
A.base[0,:,:] = B1
A.base[1,:,:] = B2
I don't think this will necessarily work for all memoryview compatible objects (they are required to define the buffer interface rather than a useful __getitem__
) but it should work for most of them, including cvarray
.