调用Cython函数时Numpy数组转ctypes int指针的问题
解决Cython函数
_select_by_peak_distance参数类型不匹配问题 问题背景
移植scipy.signal._peak_finding_utils中的Cython函数_select_by_peak_distance,函数签名:
def _select_by_peak_distance(np.intp_t[::1] peaks not None, np.float64_t[::1] priority not None, np.float64_t distance):
编译后调用时遇到两个错误:
- 传入
np.array[int]时触发:ValueError: Buffer dtype mismatch, expected 'intp_t' but got 'long'
- 尝试将数组转为ctypes指针后调用触发:
ValueError: Buffer has wrong number of dimensions (expected 1, got 0)
错误原因与解决方案
第一个错误:dtype不匹配
np.intp_t是Cython对应numpy的intp类型(即与平台指针宽度一致的整数类型,32位系统为int32,64位为int64),而非普通的int dtype。
解决方法:创建peaks数组时显式指定dtype为np.intp,无需手动转指针:
peaks = np.array([1, 4, 6, 9], dtype=np.intp) priority = np.array([0.8, 0.5, 0.9, 0.3], dtype=np.float64)
第二个错误:维度不匹配
将numpy数组转为ctypes指针后,该对象不再是一维numpy数组,Cython的内存视图np.intp_t[::1]要求传入一维数组,而非0维的指针对象,因此报错。
解决方法:直接传入符合dtype要求的一维numpy数组即可,无需转指针。
正确调用示例
import numpy as np from _peak_finding_utils import _select_by_peak_distance # 构造符合类型要求的参数 peaks = np.array([2, 5, 8, 12], dtype=np.intp) priority = np.array([0.9, 0.7, 0.8, 0.6], dtype=np.float64) distance = 3.0 # 直接调用函数 selected_peaks = _select_by_peak_distance(peaks, priority, distance)
补充说明
setup.py中compiler_directives={"language_level": "3"}的作用是指定Cython使用Python 3语法标准,例如强制使用print()函数而非print语句、整数除法默认返回浮点数等,避免Python 2的兼容问题。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

