前向き方法
はこのことを考えてみましょう:
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
1つのノート:flattend画像が10000〜100000要素の長さ(数秒)しかない場合、提案されたソリューションは本当に高速です。 2000x2000(4ミルの要素)の画像では、実際にはかなり長い時間がかかっています(まだ10分間もやっていない)。イメージが不安定になっても、それはまだ非常に速いですが、結果は期待通りです。 – user3759978
@ user3759978それは 'ベクトル化された'解を持つものです。あなたがそれを記憶の限界まで伸ばすならば、あなたは虚偽のものに頼るほうが良いです。一致しない結果については、私たちが質問から始めたときに解決策が平らになっていると仮定していると思います。 – Divakar