Ответ 1
Вы не можете применять C-функции, такие как log on numpy arrays, а numpy не имеет библиотеки функций C, которую вы можете вызывать из cython.
Функции Numpy уже оптимизированы для вызова массивов numpy. Если у вас нет очень уникального варианта использования, вы не увидите большой выгоды от переопределения функций numpy как функций C. (Возможно, некоторые функции в numpy не реализованы хорошо, в chich случае рассмотрите возможность отправки ваших вложений в виде патчей.) Однако вы действительно хорошо понимаете.
# A
from libc.math cimport log
for i in range(N):
r[i] = log(foo[i])
# B
r = np.log(foo)
# C
for i in range(n):
r[i] = np.log(foo[i])
В общем, A и B должны иметь одинаковое время выполнения, но C следует избегать и будет намного медленнее.
Update
Вот код для scipy.stats.norm.pdf, так как вы можете видеть его написанным на питоне с numpy и scipy вызовами. Существует не C-версия этого кода, вы должны называть его "через python". Если это то, что удерживает вас, вам нужно будет заново имплантировать его в C/Cython, но сначала я потрачу некоторое время на тщательное профилирование кода, чтобы увидеть, есть ли какие-нибудь более низкие висячие фрукты, которые нужно выполнить после первого.
def pdf(self,x,*args,**kwds):
loc,scale=map(kwds.get,['loc','scale'])
args, loc, scale = self._fix_loc_scale(args, loc, scale)
x,loc,scale = map(asarray,(x,loc,scale))
args = tuple(map(asarray,args))
x = asarray((x-loc)*1.0/scale)
cond0 = self._argcheck(*args) & (scale > 0)
cond1 = (scale > 0) & (x >= self.a) & (x <= self.b)
cond = cond0 & cond1
output = zeros(shape(cond),'d')
putmask(output,(1-cond0)+np.isnan(x),self.badvalue)
if any(cond):
goodargs = argsreduce(cond, *((x,)+args+(scale,)))
scale, goodargs = goodargs[-1], goodargs[:-1]
place(output,cond,self._pdf(*goodargs) / scale)
if output.ndim == 0:
return output[()]
return output