我想编写一个在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。)
答案 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
如您所见,两种情况下的地址相同。