从 numpy.ndarray 初始化 cython 中的 memoryview 切片
Initialize slices of memoryview in cython from numpy.ndarray
我正在尝试初始化内存视图的一部分(不是整个)。假设我将 memoryview A
作为 class(扩展类型)
的属性
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) 的二维数组 B1
和 B2
,并尝试初始化为
A[0,:,:] = B1
A[1,:,:] = B2
这给了我以下错误:
TypeError: only length-1 arrays can be converted to Python scalars
当然我可以将所有数据从B1
和B2
一个一个复制到A
,但是这样效率不高。这个过程是循环的,大小N
很大。 B1
和 B2
以 netcdf 文件形式加载为 numpy.ndarray
类型。
此外,我将 A
定义为 memoryview,这样我就可以在代码的其他地方使用 nogil
函数来访问 A
.
我想知道是否有一种有效的方法可以像上面那样初始化 memoryview,或者至少,以某种方式使用 B1
和 B2
的指针并将它们放在一个可迭代的数组中。谢谢。
我可以找到两个选项:
- 如果您键入
B1
和 B2
作为内存视图,它会起作用。
您可以访问内存视图的 base
属性以获取 cvarray
和索引:
A.base[0,:,:] = B1
A.base[1,:,:] = B2
我认为这不一定适用于所有 memoryview 兼容对象(它们需要定义缓冲区接口而不是有用的 __getitem__
)但它应该适用于大多数对象,包括 cvarray
.
我正在尝试初始化内存视图的一部分(不是整个)。假设我将 memoryview A
作为 class(扩展类型)
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) 的二维数组 B1
和 B2
,并尝试初始化为
A[0,:,:] = B1
A[1,:,:] = B2
这给了我以下错误:
TypeError: only length-1 arrays can be converted to Python scalars
当然我可以将所有数据从B1
和B2
一个一个复制到A
,但是这样效率不高。这个过程是循环的,大小N
很大。 B1
和 B2
以 netcdf 文件形式加载为 numpy.ndarray
类型。
此外,我将 A
定义为 memoryview,这样我就可以在代码的其他地方使用 nogil
函数来访问 A
.
我想知道是否有一种有效的方法可以像上面那样初始化 memoryview,或者至少,以某种方式使用 B1
和 B2
的指针并将它们放在一个可迭代的数组中。谢谢。
我可以找到两个选项:
- 如果您键入
B1
和B2
作为内存视图,它会起作用。 您可以访问内存视图的
base
属性以获取cvarray
和索引:A.base[0,:,:] = B1 A.base[1,:,:] = B2
我认为这不一定适用于所有 memoryview 兼容对象(它们需要定义缓冲区接口而不是有用的
__getitem__
)但它应该适用于大多数对象,包括cvarray
.