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

2024-10-04 09:19:14 发布

您现在位置:Python中文网/ 问答频道 /正文

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

对于元素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

我使用的是python2.7.13、numpy1.13.1和cython0.25.2


Tags: importfalse元素np数组cythondoubleret
1条回答
网友
1楼 · 发布于 2024-10-04 09:19:14

这并不奇怪。您的pos1pos2是C double,但是如果您将它们插入一个列表(代码中的[pos1, pos2, 0.0]),它们需要是Python对象,因为列表存储PyObject指针,因此调用PyFloat_FromDouble。你真的创建了3个包含2 pos1和2 pos2的列表,所以你最终会创建4个列表-外部的和内部的3个-并调用PyFloat_FromDouble4次。它将调用np.array,这些值将再次转换为double!你知道吗

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

相关问题 更多 >