cython中的数组数组

时间:2013-09-27 15:37:09

标签: python arrays numpy cython

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

1 个答案:

答案 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):
            ...

您可以键入subarrayobject(最适合小型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计算,同时具有美味的记忆视图界面。


这就是我所拥有的一切。拿走或离开它。