在Cython中访问NumPy记录数组列

jos*_*ers 6 python numpy cython

我是一个相对经验丰富的Python程序员,但是在很长一段时间内没有编写任何C语言并试图理解Cython.我正在尝试编写一个Cython函数,它将在NumPy重组的列上运行.

我到目前为止的代码如下.

recarray_func.pyx:

import numpy as np
cimport numpy as np

cdef packed struct rec_cell0:
  np.float32_t f0
  np.int64_t i0, i1, i2

def sum(np.ndarray[rec_cell0, ndim=1] recarray):
    cdef Py_ssize_t i
    cdef rec_cell0 *cell
    cdef np.float32_t running_sum = 0

    for i in range(recarray.shape[0]):
        cell = &recarray[i]
        running_sum += cell.f0
    return running_sum
Run Code Online (Sandbox Code Playgroud)

在翻译提示:

array = np.recarray((100, ), names=['f0', 'i0', 'i1', 'i2'],
                             formats=['f4', 'i8', 'i8', 'i8'])
recarray_func.sum(array)
Run Code Online (Sandbox Code Playgroud)

这简单地总结f0了重新排列的列.它编译并运行没有问题.

我的问题是,我如何修改它以便它可以在任何列上运行?在上面的示例中,sum的列是硬编码的,并通过点表示法访问.是否可以更改函数,以便将作为参数的列传入?

hba*_*bar 1

你想要的需要弱类型,而 C 没有。如果您的所有记录类型都相同,您可能能够完成类似的操作:(免责声明,我在这台机器上没有 Cython,所以我是盲码)。

import numpy as np
cimport numpy as np

cdef packed struct rec_cell0:
  np.float32_t f0
  np.int64_t i0, i1, i2

def sum(np.ndarray[rec_cell0, ndim=1] recarray, colname):
    cdef Py_ssize_t i
    cdef rec_cell0 *cell
    cdef np.float32_t running_sum = 0

    loc = recarray.dtype.fields[colname][1]

    for i in range(recarray.shape[0]):
        cell = &recarray[i]
        running_sum += *(int *)(&cell+loc);
    return running_sum
Run Code Online (Sandbox Code Playgroud)