从numpy.ndarray初始化cython中的memoryview切片

时间:2017-07-04 03:15:26

标签: python cython memoryview

我正在尝试初始化一个内存视图的切片(而不是整个)。假设我将memoryview A作为类的属性(扩展类型)

from cython.view cimport array as cvarray

N = 1000
cdef double[:,:,::1] A = cvarray(shape=(2,N,N),itemsize=sizeof(double),format='d')

现在,我正在尝试在cdef函数中初始化它。我没有问题像这样初始化整个内存视图

# From elsewhere we have loaded a numpy.ndarray B of size (2,N,N)
A[:,:,:] = B

当初始化程序B是3D数组(2,N,N)时,这很好,因此我们不必切片 A。但现在问题在于:假设我有大小为({N} N}的二维数组B1B2,并尝试初始化为

A[0,:,:] = B1
A[1,:,:] = B2

这给了我以下错误:

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

当然,我可以将所有数据从B1B2逐个复制到A,但这样做效率不高。此过程处于循环中,大小N很大。 B1B2 netcdf 文件加载为numpy.ndarray类型。

此外,我将A定义为 memoryview ,以便代码中的其他位置我可以使用nogil函数来访问A。< / p>

我想知道是否有一种有效的方法来初始化如上所述的内存视图,或者至少以某种方式使用B1B2的指针并将它们放在一个可迭代的数组中。感谢。

1 个答案:

答案 0 :(得分:1)

我可以找到两个选项:

  1. 如果您输入B1B2作为内存视图,则可以使用。
  2. 您可以访问memoryview的base属性以获取cvarray并索引:

    A.base[0,:,:] = B1
    A.base[1,:,:] = B2
    

    我认为这不一定适用于所有与memoryview兼容的对象(它们需要定义缓冲区接口而不是有用的__getitem__),但它应该适用于大多数,包括{{ 1}}。