python - 如果在数组创建期间定义了 NumPy 数组的元素,为什么 Cython 需要更多 Python 调用?

标签 python python-2.7 numpy cython cythonize

如果我在数组创建期间定义了数组元素 (#-1-),我不明白为什么 Cython 需要更多 Python 调用来编译我的 .pyx 文件。

对于元素 pos1pos2PyFloat_FromDouble 被调用四次,每个变量两次,但是如果我创建一个空数组或零数组,然后更改元素 (#-2-)。

import cython
import numpy as np
cimport numpy as np
from libc.math cimport sin
from libc.math cimport cos

@cython.boundcheck(False)
@cython.binding(False)
@cython.wraparound(False)
cpdef np.ndarray[np.float64_t, ndim = 2] mat (double alfa):
    cdef double pos1 = cos(alfa * 0.01745)
    cdef double pos2 = sin(alfa * 0.01745)
    cdef np.ndarray[np.float64_t, ndim = 2] mat_ret

    #-1-
    mat_ret = np.array([[pos1, pos2, 0.0],
                        [pos1, pos2, 0.0],
                        [ 0.0,  0.0, 0.0]], dtype = np.float64)

    #-2-
    mat_ret = np.zeros((3,3), dtype = np.float64)
    mat_ret[0,0] = pos1
    mat_ret[0,1] = pos2
    mat_ret[1,0] = pos1
    mat_ret[1,1] = pos2

    return mat_ret

我正在使用 Python 2.7.13、NumPy 1.13.1 和 Cython 0.25.2

最佳答案

这应该不足为奇。您的 pos1pos2 是 C double ,但如果您将它们插入列表中(代码中的 [pos1, pos2, 0.0])它们需要是 Python 对象,因为列表存储 PyObject 指针,从而调用 PyFloat_FromDouble。您实际上创建了 3 个包含 2 个 pos1 和 2 个 pos2 列表,因此您最终将创建 4 个列表 - 外部列表和内部 3 个列表 - 并调用 PyFloat_FromDouble 4次。它将调用 np.array,其中这些值将再次转换为 double!

另一方面,如果您创建具有“适当”数据类型的 np.zeros 数组,则它可以只插入 double 。因为它不必将它们插入到中间 Python 对象中,所以根本不需要将它们装箱 (PyFloat_FromDouble)。

关于python - 如果在数组创建期间定义了 NumPy 数组的元素,为什么 Cython 需要更多 Python 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45651046/

相关文章:

Python - 只有最后一行被保存到文件

python - MetPy 中的 Pint Python 模块 - pint.UnitRegistry TypeError - 意外的关键字参数

c++ - 如何使用 boost::python 从派生类获取所有类属性名称?

numpy - 如何将填充 RGB 图像归零?

python - numpy.savetxt 一维数组写入问题

python - Pandas groupby + scikit learn 电源变压器

python - 用于股市预测的情绪词典

python - 如何在python中将成员函数作为参数传递?

Python PANDAS : New Column, 将唯一值应用于所有行

numpy - 如何将距离数据插入 scipy 的凝聚聚类方法?