Я пытаюсь использовать 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
Ячейка записной книжки работает успешно, как написано, поэтому я подумал, что обе функции скомпилированы успешно. Однако этот код выполняется должным образом:
%timeit rand_df.apply(breadth_c_type, raw=True)
, тогда как этот код:
%timeit rand_df.apply(evenness_c_type, raw=True)
не запускается и возвращает «NameError: name 'evenness_c_type' не определено». Я получаю те же результаты без декоратора% timeit, и функции не компилируются при использовании «cpdef» или «def» вместо «cdef». Поскольку я пытался следовать одинаковому синтаксису для обеих функций, я не знаю, что вызывает ошибку для evenness_c_type.
EDIT Благодаря @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)