Медленная часть вычислений выглядит как строка np.percentile(new_arr[((new_arr >= np.percentile(new_arr,15)) & (new_arr <= np.percentile(new_arr,85)))],99)
. Это связано с неожиданно медленным np.percentile
на небольших массивах, а также с созданием нескольких промежуточных массивов.
Поскольку new_arr
на самом деле довольно маленький, гораздо быстрее просто отсортировать его и произвести интерполяцию сами. Более того, numba также может помочь ускорить вычисления.
@njit #Use @njit instead of @jit to increase speed
def filter(arr):
arr = arr.copy() # This line can be removed to modify arr in-place
arr.sort()
lo = int(math.ceil(len(arr)*0.15))
hi = int(len(arr)*0.85)
interp = 0.99 * (hi - 1 - lo)
interp = interp - int(interp)
assert lo <= hi-2
return arr[hi-2]* (1.0 - interp) + arr[hi-1] * interp
Этот код в 160 раз быстрее с массивами размера 20 на моей машине и должен давать тот же результат.
Наконец, вы также можете ускорить smooth_surface
, используя автоматическое c распараллеливание в numba (см. здесь для получения дополнительной информации). Вот непроверенный прототип:
@jit(parallel=True)
def smooth_surface(z,c):
hph_arr = np.zeros(len(z)-(c+1)-c)
for x in prange(c,len(z)-(c+1)):
hph_arr[x-c] = filter(np.hstack(z[x-c:x+c]))
return hph_arr