将Numpy数组转换为ctypes `int`指针,以便从Python调用Cython函数

cpjpxq1n  于 2023-06-23  发布在  Python
关注(0)|答案(1)|浏览(101)

我正在尝试供应商的方法_select_by_peak_distancescipy.signal._peak_finding_utils。这是一个cython .pyx文件,函数具有签名:

def _select_by_peak_distance(np.intp_t[::1] peaks not None,
                             np.float64_t[::1] priority not None,
                             np.float64_t distance):

我已经在本地使用下面的www.example.com文件重新编译了_peak_finding_utils.pyxsetup.py。
我已经将函数导入到Python中,现在正在尝试调用它。我很天真地开始用np.array[int], np.array[float], float调用,但是我得到了一个与第一个参数相关的错误:

*** ValueError: Buffer dtype mismatch, expected 'intp_t' but got 'long'

我看到第一个参数应该是一个指向整数数组的指针,而不是整数。因此,我尝试根据numpy ctypes文档将numpy数组转换为指针:

pointer = my_array.ctypes.data_as(ctypes.POINTER(ctypes.c_int))

但是,使用此参数调用函数会导致错误:

*** ValueError: Buffer has wrong number of dimensions (expected 1, got 0)

我已经研究了这一点,但找不到根本原因,并觉得像int铸造程序是错误的。任何帮助将不胜感激。
setup.py

from distutils.core import setup
from Cython.Build import cythonize
import numpy

setup(
    ext_modules=cythonize(
        "_peak_finding_utils.pyx", compiler_directives={"language_level": "3"},  # TODO: what does this do.
    ),
    include_dirs=[numpy.get_include()]
)
gmol1639

gmol16391#

我相信你想用peaks.astype(np.intp)来调用它,对于你的优先级数组,用np.float64来调用它,例如:

# dummy data
peaks = np.array([1, 2, 3])
priority = np.array([0.1, 0.2, 0.3])
distance = 0.5

select_by_peak_distance(peaks.astype(np.intp), priority.astype(np.float64), distance)

请注意,如果在64位平台上peeks数组中的值超过2^63-1(在32位平台上超过2^31-1),则此操作将失败

相关问题