【问题标题】:Would like to vectorize while loop for performance (updated)想要对 while 循环进行矢量化以提高性能(已更新)
【发布时间】:2019-09-10 02:21:48
【问题描述】:
  1. 根据另一个数组的当前值设置数组大小为 n 的窗口的值
  2. 忽略窗口覆盖的值
  3. 需要能够为不同的运行更改窗口大小 (n)

此代码有效,但速度很慢。

    n = 3

    def signal(arr):
        signal = pd.Series(data=0, index=arr.index)
        i = 0
        while i < len(arr) - 1: 
            s = arr.iloc[i]
            if s in [-1, 1]:
                j = i + n
                signal.iloc[i: j] = s
                i = i + n
            else:
                i += 1
        return signal
arr = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0]

signal = [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0]

【问题讨论】:

  • 你能把你的问题说得更清楚一些,比如你的输入是什么,你的期望输出是什么?在代码形成中。
  • 更新:arr 是输入 - 信号是输出
  • 请提供arr作为机器可读代码。

标签: python numpy vectorization


【解决方案1】:

不要将 arr 设为 pandas 系列对象,而应将其设为 numpy 数组。 试试这个:

import numpy as np
def signal(arr, n):
    size = len(arr)
    signal = np.zeros(size)
    for i in range(size):
        s = arr[i]
        if s in [-1, 1]:
            j = i + n
            signal[i: j] = s
            i = i + n
        else:
            i += 1
    return signal
arr = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0]
n = 3

signal(arr, n)

我对两种不同的解决方案进行了基准测试,这样更快:

  • 原始:每个循环 738 µs ± 21.9 µs(平均值 ± 标准偏差,7 次运行,1000 每个循环)
  • 新:每个循环 9.56 µs ± 778 ns(平均值 ± 标准偏差,7 次运行,100000 每个循环)

【讨论】:

  • 这需要将 for 循环替换为 i = 0; while i &lt; len(arr) :for i in range... 在每次迭代时重置 i,因此消除了 i=i+n 的影响。它比我尝试过的任何其他方法都快得多。
猜你喜欢
  • 2021-03-13
  • 2017-03-13
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多