如何在cython中获取指向ndarray数据(任何维度)的开始

时间:2018-01-12 18:47:18

标签: python cython

我想编写一个在ndarray(任何维度)上运行的函数。

我发现的cython示例如下:

@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False)  # turn off negative index wrapping for entire function
def c_fill_na_inplace_f64(np.ndarray[np.int64_t, cast=False, mode="c"] X, np.int64_t fillval):
    cdef size_t N = X.size
    cdef np.int64_t* = &X[0]

但是,我怀疑对于不同尺寸的数组我需要不同的索引:

    cdef np.int64_t* = &X[0]
    cdef np.int64_t* = &X[0,0]
    cdef np.int64_t* = &X[0,0,0]

有没有更好的方法来获得数据的开始。

就此而言,如何编写一个采用任何维度的ndarray的函数?假设np.ndarray[ndim=1...未提供ndim

(注意:由于const bug,我无法使用MemoryView。)

1 个答案:

答案 0 :(得分:1)

可能困难的部分是让签名正确。我会使用泛型python-object + reshape(-1),它会将数组重新解释为一维数组而不进行复制。

这是一个有点草率的例子。它至少适用于连续数组,对于其他数组来说它更复杂,也因为必须让C代码知道它并且仅仅传递指针&X[0]是不够的:

%%cython
cimport numpy as np
def print_nd(object X):
    cdef np.ndarray[np.int64_t] arr=X.reshape(-1)
    cdef np.int64_t *ptr=&arr[0]
    print("addr", <np.uint64_t>(ptr))
    print("ptr1:", ptr[0])

这里是一个测试(对于2-dim数组):

%%cython
cimport numpy as np
def print_2d(np.ndarray[np.int64_t, ndim=2] X):
    cdef np.int64_t *ptr=&X[0,0]
    print("addr", <np.uint64_t>(ptr))
    print("ptr1:", ptr[0])

>>> print_nd(a)
addr 94635612809360
ptr1: 1
>>> print_2d(a)
addr 94635612809360
ptr1: 1

如您所见,两种情况下的地址相同。