cython中的数组数组

dan*_*anb 6 python arrays numpy cython

如何在cython中声明一个数组数组?

更确切地说,我想构造(声明然后初始化)一个m乘n矩阵,称之为A,其中每个条目[i,j]是一个1维的双精度数组(长度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)
Run Code Online (Sandbox Code Playgroud)

对于(m,n)=(4,3),print A应返回如下内容:

[[[], [], []],
[[], [0.], [0.]],
[[], [0.], [0.,0.]],
[[], [0.], [0.,0.]]]
Run Code Online (Sandbox Code Playgroud)

我如何申报和初始化A?

Vee*_*rac 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
Run Code Online (Sandbox Code Playgroud)

请注意,该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):
            ...
Run Code Online (Sandbox Code Playgroud)

你可以键入subarrayobject(最适合小subarrayS)或float[:](最适合大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
Run Code Online (Sandbox Code Playgroud)

基本上,制作3D阵列和相应长度的2D阵列.如果长度只有一个线性变化(所以最大长度是一个合理的因素[我说平均长度大约10])那么这应该是可接受的开销.它将允许纯C计算,同时具有美味的内存视图界面.


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