Как уже отмечалось в других ответах, почти всегда следует избегать (и можно) избегать итерации по элементам массива numpy
в цикле Python.В большинстве случаев переход от цикла Python к операции с массивом дает ускорение ~ 100x.
Однако, если производительность абсолютно критична, вы часто можете выжать еще один фактор между 2x и 10x (по моему опыту)используя Cython .Вот пример:
%%cython
cimport numpy as np
import numpy as np
cimport cython
from cython cimport floating
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef np.ndarray[floating, ndim=1] beta(np.ndarray[floating, ndim=1] arr):
cdef:
Py_ssize_t i
Py_ssize_t N = arr.shape[0]
np.ndarray[floating, ndim=1] result = np.zeros(N)
for i in range(N):
if arr[i] < 0.5:
result[i] = 2.0*arr[i]
else:
result[i] = 1.0/(2.0*(1.0-arr[i]))
return result
Тогда вы бы назвали его beta(rand)
.Как вы можете видеть, это позволяет использовать исходную структуру цикла, но теперь использовать эффективный типизированный нативный код.Я получаю ускорение примерно в 2,5 раза по сравнению с np.where
.
Следует отметить, что во многих случаях это не стоит дополнительных усилий по сравнению с однострочником в numpy
- но это можетхорошо, где производительность имеет решающее значение.