对象方法:
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
best for small subarray
s) 或float[:]
(best for large subarray
s)。
事实证明,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 计算,同时具有美味的 memoryview 界面。
这就是我所拥有的。要么接受,要么离开它。