有没有更快的方法来添加两个2-d numpy数组

有没有更快的方法来添加两个2-d numpy数组,第1张

有没有更快的方法来添加两个2-d numpy数组 方法1(矢量化)

我们可以

modulus
用来模拟的传播行为,
roll/circshift
并通过广播索引覆盖所有行,我们将拥有一种完全矢量化的方法,如下所示:

n = b.shape[0]idx = n-1 - np.mod(shift.cumsum()[:,None]-1 - np.arange(n), n)a += b[idx].sum(0)
方法2(循环1)
b_ext = np.row_stack((b, b[:-1] ))start_idx = n-1 - np.mod(shift.cumsum()-1,n)for j in range(start_idx.size):    a += b_ext[start_idx[j]:start_idx[j]+n]

冒号表示法与使用索引进行切片

一旦进入循环,这里的想法就是做最少的工作。在进入循环之前,我们正在预先计算每个迭代的起始行索引。因此,我们在循环内需要做的所有事情就是使用冒号表示法切片,这是对数组的视图并累加。这应该比

rolling
需要计算所有行索引而导致产生昂贵副本的行索引要好得多。

在对冒号和索引进行切片时,这里会更多地介绍视图和复制概念-

In [11]: a = np.random.randint(0,9,(10))In [12]: aOut[12]: array([8, 0, 1, 7, 5, 0, 6, 1, 7, 0])In [13]: a[3:8]Out[13]: array([7, 5, 0, 6, 1])In [14]: a[[3,4,5,6,7]]Out[14]: array([7, 5, 0, 6, 1])In [15]: np.may_share_memory(a, a[3:8])Out[15]: TrueIn [16]: np.may_share_memory(a, a[[3,4,5,6,7]])Out[16]: False

运行时测试

功能定义-

def original_loopy_app(a,b):    for j in range(shift.size):        b=np.roll(b, shift[j] , axis=0)        a += bdef vectorized_app(a,b):    n = b.shape[0]    idx = n-1 - np.mod(shift.cumsum()[:,None]-1 - np.arange(n), n)    a += b[idx].sum(0)def modified_loopy_app(a,b):    n = b.shape[0]    b_ext = np.row_stack((b, b[:-1] ))    start_idx = n-1 - np.mod(shift.cumsum()-1,n)    for j in range(start_idx.size):        a += b_ext[start_idx[j]:start_idx[j]+n]

情况1:

In [5]: # Setup input arrays   ...: N = 200   ...: M = 1000   ...: a = np.random.randint(11,99,(N,N))   ...: b = np.random.randint(11,99,(N,N))   ...: shift = np.random.randint(0,N,M)   ...:In [6]: original_loopy_app(a1,b1)   ...: vectorized_app(a2,b2)   ...: modified_loopy_app(a3,b3)   ...:In [7]: np.allclose(a1, a2) # Verify resultsOut[7]: TrueIn [8]: np.allclose(a1, a3) # Verify resultsOut[8]: TrueIn [9]: %timeit original_loopy_app(a1,b1)   ...: %timeit vectorized_app(a2,b2)   ...: %timeit modified_loopy_app(a3,b3)   ...: 10 loops, best of 3: 107 ms per loop10 loops, best of 3: 137 ms per loop10 loops, best of 3: 48.2 ms per loop

情况2:

In [13]: # Setup input arrays (datasets are exactly 1/10th of original sizes)    ...: N = 200    ...: M = 10000    ...: a = np.random.randint(11,99,(N,N))    ...: b = np.random.randint(11,99,(N,N))    ...: shift = np.random.randint(0,N,M)    ...:In [14]: %timeit original_loopy_app(a1,b1)    ...: %timeit modified_loopy_app(a3,b3)    ...: 1 loops, best of 3: 1.11 s per loop1 loops, best of 3: 481 ms per loop

因此,我们正在考虑

2x+
使用改进的循环方法来提高速度!



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5562364.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存