有关如何加快此 python 功能的建议?
Suggestions on how to speed up this python function?
关于如何加速这个功能有什么建议吗?
def smooth_surface(z,c):
hph_arr_list = []
for x in xrange(c,len(z)-(c+1)):
new_arr = np.hstack(z[x-c:x+c])
hph_arr_list.append(np.percentile(new_arr[((new_arr >= np.percentile(new_arr,15)) & (new_arr <= np.percentile(new_arr,85)))],99))
return np.array(map(float,hph_arr_list))
变量 z
的长度约为 1500 万,c
是 window 大小 +
和 -
的值。该函数基本上是一个滑动 window,它计算每次迭代的百分位值。任何帮助,将不胜感激! z
是数组的数组(因此是 np.hstack
)。也许知道 numba 是否会对此有所帮助。如果可以,如何实现?
计算速度较慢的部分似乎是行 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
此代码在我的机器上使用大小为 20 的数组时速度快 160 倍,并且应该产生相同的结果。
最后,您还可以通过在 numba 中使用自动并行化来加快 smooth_surface
(有关详细信息,请参阅 here)。这是一个未经测试的原型:
@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
关于如何加速这个功能有什么建议吗?
def smooth_surface(z,c):
hph_arr_list = []
for x in xrange(c,len(z)-(c+1)):
new_arr = np.hstack(z[x-c:x+c])
hph_arr_list.append(np.percentile(new_arr[((new_arr >= np.percentile(new_arr,15)) & (new_arr <= np.percentile(new_arr,85)))],99))
return np.array(map(float,hph_arr_list))
变量 z
的长度约为 1500 万,c
是 window 大小 +
和 -
的值。该函数基本上是一个滑动 window,它计算每次迭代的百分位值。任何帮助,将不胜感激! z
是数组的数组(因此是 np.hstack
)。也许知道 numba 是否会对此有所帮助。如果可以,如何实现?
计算速度较慢的部分似乎是行 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
此代码在我的机器上使用大小为 20 的数组时速度快 160 倍,并且应该产生相同的结果。
最后,您还可以通过在 numba 中使用自动并行化来加快 smooth_surface
(有关详细信息,请参阅 here)。这是一个未经测试的原型:
@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