我正在尝试在 Cython 中进行严重依赖于一些 numpy/scipy 数学函数的计算,例如numpy.log
. 我注意到,如果我在 Cython 的循环中反复调用 numpy/scipy 函数,则会产生巨大的间接成本,例如:
import numpy as np
cimport numpy as np
np.import_array()
cimport cython
def myloop(int num_elts):
cdef double value = 0
for n in xrange(num_elts):
# call numpy function
value = np.log(2)
这是非常昂贵的,大概是因为np.log
通过 Python 而不是直接调用 numpy C 函数。如果我将该行替换为:
from libc.math cimport log
...
# calling libc function 'log'
value = log(2)
那么它要快得多。但是,当我尝试将一个 numpy 数组传递给 libc.math.log 时:
cdef np.ndarray[long, ndim=1] foo = np.array([1, 2, 3])
log(foo)
它给出了这个错误:
TypeError: only length-1 arrays can be converted to Python scalars
我的问题是:
- 是否可以调用 C 函数并将其传递给 numpy 数组?或者它只能用于标量值,这需要我编写一个循环(例如,如果我想将它应用于
foo
上面的数组。) - 有没有类似的方法可以直接从 C 调用 scipy 函数而无需 Python 开销?如何导入 scipy 的 C 函数库?
具体示例:假设您想在Cythonscipy.stats.*
中的循环内对标量值调用许多 scipy 或 numpy 有用的统计函数(例如)for
?在 Cython 中重新实现所有这些函数很疯狂,因此必须调用它们的 C 版本。例如,所有与 pdf/cdf 相关的函数以及来自各种统计分布的采样(例如,参见http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.pdf.html#scipy. stats.rv_continuous.pdf和http://www.johndcook.com/distributions_scipy.html)如果你在循环中使用 Python 开销调用这些函数,它会非常慢。
谢谢。