前瞻性方法
考虑一下:
In [154]: B = np.arange(5)
In [155]: B
Out[155]: array([0, 1, 2, 3, 4])
使用B
轧制版本:
In [156]: for i in range(len(B)):
...: print np.roll(B, i)
...:
[0 1 2 3 4]
[4 0 1 2 3]
[3 4 0 1 2]
[2 3 4 0 1]
[1 2 3 4 0]
所以,我们所需要的技巧聘请是创建一个扩展数组,可以切片以获取滚动版本。这个想法在NumPy中切片基本上是免费的。由此,扩展阵列将是 -
In [157]: B_ext = np.concatenate((B[1:], B))
In [158]: B_ext
Out[158]: array([1, 2, 3, 4, 0, 1, 2, 3, 4])
因此,在切片步骤将是 -
[1, 2, 3, 4, 0, 1, 2, 3, 4]
[ ]
[ ]
[ ]
[ ]
[ ]
用它
然后,扩展阵列可以使用像这样 -
n = len(A)
for i in range(n-1,-1,-1):
Ac *= B_ext[i:i+n] #roll B with i-increment and multiply
Ac[n-1-i] += sum_arr #add sum to A at index
完成
结束写入,所述方法将是 -
def org_app(A, B, sum_arr): # Original approach
for i in range(len(A)):
A = np.multiply(A, np.roll(B, i)) #roll B with i-increment and multiply
A[i] += sum_arr #add sum to A at index
return A
def app1(A, B, sum_arr): # Proposed approach
B_ext = np.concatenate((B[1:], B))
n = len(A)
for i in range(n-1,-1,-1):
A *= B_ext[i:i+n] #roll B with i-increment and multiply
A[n-1-i] += sum_arr #add sum to A at index
return A
标杆
1)验证 -
In [144]: # Setup inputs
...: np.random.seed(1234)
...: N = 10000
...: A = np.random.randint(0,255,(N))
...: B = np.random.randint(0,255,(N))
...: A_copy = A.copy()
...: sum_arr = np.sum(B) #sum of B
...:
In [145]: out1 = org_app(A, B, sum_arr)
...: out2 = app1(A_copy, B, sum_arr)
...: print "Abs. Max. Error : " + str(np.abs(out1-out2).max())
...:
Abs. Max. Error : 0
2)运行测试 -
In [146]: # Setup inputs
...: np.random.seed(1234)
...: N = 10000
...: A = np.random.randint(0,255,(N))
...: B = np.random.randint(0,255,(N))
...: A_copy = A.copy()
...: sum_arr = np.sum(B) #sum of B
...:
In [147]: %timeit org_app(A, B, sum_arr)
1 loop, best of 3: 196 ms per loop
In [148]: %timeit app1(A_copy, B, sum_arr)
10 loops, best of 3: 51.9 ms per loop
哇!快4倍!相当漂亮的想法,我没有想过切片:) – user3759978
一个注意:当flattend图像只有10000到100000个元素(几秒)时,所提出的解决方案确实更快。对于2000x2000(4毫米的元素)图像来说,它需要更长的时间(10分钟后仍然没有完成)。奇怪的是,当图像不平坦时仍然非常快,但结果并不像预期的那样。 – user3759978
@ user3759978这就是'矢量化'解决方案。如果你把它扩展到内存限制,你最好使用一个loopy。关于结果不匹配,我认为这是因为解决方案在我们开始讨论问题时采用了扁平化版本。 – Divakar