あなたはそれらのネストされたループを削除するためにNumPy broadcasting
を使用することができます -
C = D[N + np.arange(N)[:,None] - np.arange(N)]
そうのようなものでも、インデックスを置き換えるためにnp.take
を使用することができます -
C = np.take(D,N + np.arange(N)[:,None] - np.arange(N))
よく見るが近いようにパターンを明らかにするおよびhankel
マトリクス。だから、それらを使って、私たちはそれを解決するための2つのアプローチを持っていますが、放送と同等のスピードアップがあります。実装は、これらのようになります -
from scipy.linalg import toeplitz
from scipy.linalg import hankel
C = toeplitz(D[N:],np.hstack((D[0],D[N-1:0:-1])))
C = hankel(D[1:N+1],D[N:])[:,::-1]
ランタイムテスト
In [230]: M = 1000
...: t = np.arange(M)
...: D = np.sin(t) # initial vector is a sin() function
...: N = M/2
...:
In [231]: def org_app(D,N):
...: C = np.zeros((N,N))
...: for a in xrange(N):
...: for b in xrange(N):
...: C[a,b] = D[N + a - b]
...: return C
...:
In [232]: %timeit org_app(D,N)
...: %timeit D[N + np.arange(N)[:,None] - np.arange(N)]
...: %timeit np.take(D,N + np.arange(N)[:,None] - np.arange(N))
...: %timeit toeplitz(D[N:],np.hstack((D[0],D[N-1:0:-1])))
...: %timeit hankel(D[1:N+1],D[N:])[:,::-1]
...:
10 loops, best of 3: 83 ms per loop
100 loops, best of 3: 2.82 ms per loop
100 loops, best of 3: 2.84 ms per loop
100 loops, best of 3: 2.95 ms per loop
100 loops, best of 3: 2.93 ms per loop
すごいです!これは、ループを大幅に高速化しました。 – jjgoings
@jjgoingsうん、それを確認した! – Divakar