Я пытаюсь сделать вычисления в Cython, которые в значительной степени полагаются на некоторые математические функции numpy/scipy, такие как numpy.log
. Я заметил, что если я повторяю несколько циклов numpy/scipy в цикле в Cython, есть огромные накладные расходы, например:
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
выше). - Есть ли аналогичный способ вызова scipy-функций из C напрямую без накладных расходов Python? Каким образом я могу импортировать библиотеку функций Scipy C?
Конкретный пример: скажем, вы хотите называть многие из scipy или numpy полезных статистических функций (например, scipy.stats.*
) для скалярных значений внутри цикла for
в Cython? Это сумасшедшее, чтобы переопределить все эти функции в 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 в цикле, это будет непомерно медленным.
спасибо.