6

如何在 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?

4

1 回答 1

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( objectbest for small subarrays) 或float[:](best for large subarrays)。


事实证明,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 界面。


这就是我所拥有的。要么接受,要么离开它。

于 2013-09-27T16:46:11.927 回答