前瞻性方法
考慮一下:
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