【发布时间】:2020-03-11 16:28:39
【问题描述】:
我正在尝试使用 Cython 来加速我的 Python 脚本的某些部分。一个关键部分将函数应用于 Pandas 数据框;因为这做了很多次,所以我想用 Cython 编写这些函数以加快计算速度。函数如下,并且位于同一个 Jupyter 笔记本单元格中:
%%cython
cimport numpy as np
import numpy as np
cdef double breadth_c_type(np.ndarray[np.float64_t, ndim=1] arr):
""" Calculates range between the maximum and minimum values of a given list. """
return (max(arr) - min(arr))
cdef double evenness_c_type(np.ndarray[np.float64_t, ndim=1] arr):
""" Calculates the sample variance of differences between values in a sorted list. """
cdef np.ndarray[double] sorted_arr
cdef list desc_diff
cdef double m
cdef double var_res
sorted_arr = sorted(arr)
desc_diff = []
for x in range(len(arr)-1):
desc_diff.append(sorted_arr[x+1]-sorted_arr[x])
# following used to avoid usage of numpy
m = sum(desc_diff) / len(desc_diff)
var_res = sum((xi - m)**2 for xi in desc_diff) / len(desc_diff)
return var_res
notebook cell 运行成功,所以我认为这两个函数都编译成功了。但是,此代码按预期运行:
%timeit rand_df.apply(breadth_c_type, raw=True)
而这段代码:
%timeit rand_df.apply(evenness_c_type, raw=True)
不运行,并返回“NameError: name 'evenness_c_type' is not defined”。如果没有 %timeit 装饰器,我会得到相同的结果,并且当使用 'cpdef' 或 'def' 代替 'cdef' 时,函数不会编译。由于我尝试对这两个函数使用相同的语法,所以我不知道是什么导致了 evenness_c_type 的错误。
编辑
感谢@DavidW,我发现了evenness_c_type() 函数的问题。它编译和运行良好,虽然不如普通 Cython 版本快。
cdef double evenness_c_type(np.ndarray[np.float64_t, ndim=1] arr):
""" Calculates the population variance of differences between values in a sorted list. """
cdef np.ndarray [double] desc_diff=np.empty(len(arr)-1, dtype = np.float64)
arr.sort()
for x in range(len(arr)-1):
desc_diff[x]=(arr[x+1]-arr[x])
return np.var(desc_diff)
【问题讨论】:
标签: python-3.x numpy cython