【问题标题】:Faster loop operating on two values of an array对数组的两个值进行更快的循环
【发布时间】:2016-02-07 04:03:42
【问题描述】:

考虑以下函数:

def dostuff(n, f):
    array = numpy.arange(0, n)
    for i in range(1, n):                    # Line 1                      
        array[i] = f(array[i-1], array[i])   # Line 2
    return numpy.sum(array)

如何重写第 1 行/第 2 行以使 python 3 中的循环更快(不使用 cython)?

【问题讨论】:

  • 你看过numpy.vectorize吗?文档说这主要是为了方便,但在某些情况下可能会有所收获。
  • 你将如何使用 Python 向量化来做到这一点?
  • 你的函数f完全是自定义函数吗?或者它可能由numpy 在某处实现?你能分享一下它的实现吗
  • f 可以是任何取两个整数并返回一个整数
  • 在我看来,用例过于简单,无法真正利用 numpy 的优势。我没有计时,但也许像sum(f(x, x+1) for x in range(n-1)) 这样的东西实际上会更快?

标签: python loops numpy optimization numpy-ufunc


【解决方案1】:

我鼓励你在 SO generalized cumulative functions in NumPy/SciPy? 上检查这个问题,因为你想要一个 generalized cumulative function

还可以查看函数 frompyfunc Here 的 scipy 文档

func = np.frompyfunc(f , 2 , 1)

def dostuff(n,f):
    final_array = func.accumulate(np.arange(0,n), dtype=np.object).astype(np.int)
    return np.sum(final_array)

示例


In [86]:
def f(num1 , num2):
    return num1 + num2

In [87]:
func = np.frompyfunc(f , 2 , 1)

In [88]:
def dostuff(n,f):
    final_array = func.accumulate(np.arange(0,n), dtype=np.object).astype(np.int)
    return np.sum(final_array)

In [108]:
dostuff(15,f)
Out[108]:
560

In [109]:
dostuff(10,f)
Out[109]:
165

基准


def dostuff1(n, f):
    array = np.arange(0, n)
    for i in range(1, n):                    # Line 1                      
        array[i] = f(array[i-1], array[i])   # Line 2
    return np.sum(array)

def dostuff2(n,f):
    final_array = func.accumulate(np.arange(0,n), dtype=np.object).astype(np.int)
    return np.sum(final_array)

In [126]:
%timeit dostuff1(100,f)
10000 loops, best of 3: 40.6 µs per loop

In [127]:
%timeit dostuff2(100,f)
The slowest run took 4.98 times longer than the fastest. This could mean that an intermediate result is being cached 
10000 loops, best of 3: 23.8 µs per loop

【讨论】:

  • 除了非矢量化版本返回[0,1,3,6]我猜
  • 我遇到了这个问题,这有点棘手:),我已经更新了我的答案
猜你喜欢
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多