【问题标题】:Suggestions on how to speed up this python function?关于如何加速这个python函数的建议?
【发布时间】:2020-06-18 16:39:39
【问题描述】:

有关如何加快此功能的任何建议?

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 是窗口大小+- 的值。该函数基本上是一个滑动窗口,每次迭代计算一个百分位值。任何帮助,将不胜感激! z 是一个数组数组(因此是 np.hstack)。也许任何想法 numba 会对此有所帮助。如果有,如何实施?

【问题讨论】:

  • xrange 建议这是 Python2 的代码。这是正确的吗?
  • 是的,这是 python 2。对不起,应该添加的
  • 确切地说是 2.7
  • 实际窗口大小有多大? z 中子数组的平均大小是多少?
  • 如果您在问题中包含一个可重现的示例,其中还包括经过的时间,您可能会得到一些更有用的结果。这意味着添加输入数据、导入和输出数据。天真地,滑动窗口可能是您可以加速的东西

标签: python python-2.7 performance cython numba


【解决方案1】:

计算的缓慢部分似乎是np.percentile(new_arr[((new_arr &gt;= np.percentile(new_arr,15)) &amp; (new_arr &lt;= 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

【讨论】:

  • 非常感谢!我什至从未想过自己用一个单独的函数来计算它。我将在我的代码中尝试一下。再次感谢。这可以在运行时为我节省几个小时(或更多)
  • 看起来我在没有“并行”选项和“prange”的情况下被卡住了,直到我更新到更高版本的 numba(目前有 0.33)。即使没有这 100 万次迭代,也从约 32 秒变为约 9.4 秒。再次感谢!
  • 对于任何看到这一点的人......使用@njit(fastmath=True) 作为“过滤器”功能有助于加快速度。应该提到的是,这用于 python 3.9,这与原始问题(使用 python 2.7 的地方)不同
猜你喜欢
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
相关资源
最近更新 更多