如何在cython中声明一个数组数组?
更确切地说,我想构造(声明然后初始化)一个m乘n矩阵,称之为A,其中每个条目[i,j]是一个双维的数组(长度为min(i,j)
形式为
cdef np.ndarray[np.double_t, ndim=1] A[i,j]
A[i,j] = np.zeros((min(i,j)), dtype=np.double)
对于(m,n)=(4,3),print A
应返回如下内容:
[[[], [], []],
[[], [0.], [0.]],
[[], [0.], [0.,0.]],
[[], [0.], [0.,0.]]]
如何声明和初始化A?
答案 0 :(得分:7)
对象方法:
import numpy
def thing(int m, int n):
cdef int i, j
cdef object[:, :] A = numpy.empty((m, n), dtype=object)
for i in range(A.shape[0]):
for j in range(A.shape[1]):
A[i, j] = numpy.zeros(min(i, j))
return A
请注意,object[:, :]
语法是较新版本,不推荐numpy.ndarray[object, ndim=2]
版本。较新的版本是GIL免费的(好吧,可能不是在使用object
类型时),通常更快(从不慢),类型不可知(适用于支持memoryview
的任何事情)和更清洁。
如果你想迭代子数组,你将会这样做:
for i in range(A.shape[0]):
for j in range(A.shape[1]):
subarray = A[i, j]
for k in range(subarray.size):
...
您可以键入subarray
至object
(最适合小型subarray
)或float[:]
(最适合大型subarray
)。
C级解决方案被证明非常棘手。我有一种感觉,你基本上最终会用纯C类型写它。
所以我放弃了,这就是我要做的事情:
import numpy
def thing(int m, int n):
cdef int i, j
cdef float[:, :, :] A = numpy.zeros((m, n, min(m, n)), dtype=float)
cdef int[:, :] A_lengths = numpy.empty((m, n), dtype=int)
for i in range(A_lengths.shape[0]):
for j in range(A_lengths.shape[1]):
A_lengths[i, j] = min(i, j)
return A, A_lengths
基本上,制作一个3D数组和相应长度的2D数组。如果长度只有一个线性变化(所以最大长度是一个合理的因素[我说平均长度大约10])那么这应该是可接受的开销。它将允许纯C计算,同时具有美味的记忆视图界面。
这就是我所拥有的一切。拿走或离开它。