2016-04-06 12 views
0

I次のPythonコードを持っている:Uは十分長いので、無境界のうち、エラーが発生するベクトルである行列の列を反復的かつ高速に設定する方法は?

H = np.zeros(shape=(N-q+1,q),dtype=complex) 
for i in range(0,N-q+1): 
    H[i,:] = u[i:q+i] 
NQは定数で

の場合U [I:Q + i]

私はが前のコードよりも、それが遅くなるnp.asarray()

H = np.asarray([u[i:q+i] for i in range(0,N-q+1)]) 

しかし、リストの内包を使用してコードを最適化することを試みました。

列の値の割り当てを最適化するためのアイデアはありますか?

+0

私が行う既存のルーチンであることが覚えていますこれは非常に密接に関連していますが、私はそれが何であるか覚えていません。 'i'値のシンプルさは、既存のルーチンがなければ、明示的なストライド操作でこれを行うことができることを意味します。 – user2357112

+0

待って、いいえ、私は別のことを考えていました。 – user2357112

+0

実際に実行される例を追加できますか? – Chiel

答えて

2

あなたがstride.as_stridedを使用することができる:

import numpy.lib.stride_tricks as stride 

s = u.strides[0] 
H2 = stride.as_strided(u, shape=(N-q+1,q), strides=(s, s)).astype(complex) 

strides=(s, s)を使用するキーである - 特に、最初のストライドsを作ることH2の各行が前進するために必要なバイト数によってuへのインデックスを進めることを意味します一品。したがって、行は1つずつシフトしますが、繰り返されます。 stride.as_stridedので


例えば、

import numpy as np 
import numpy.lib.stride_tricks as stride 

N, q = 10**2, 6 
u = np.arange((N-q+1)*(N)) 

def using_loop(u): 
    H = np.zeros(shape=(N-q+1,q),dtype=complex) 
    for i in range(0,N-q+1): 
     H[i,:] = u[i:q+i] 
    return H 

def using_stride(u): 
    s = u.strides[0] 
    H2 = stride.as_strided(u, shape=(N-q+1,q), strides=(s, s)).astype(complex) 
    return H2 

H = using_loop(u) 
H2 = using_stride(u) 
assert np.allclose(H, H2) 

パイソンfor-loopusing_strideusing_loopより速い回避します。この利点は、N-q(反復回数)が増えるほど大きくなります。 Nで

= 10 ** 2 using_stride速く5倍である:Nで

In [119]: %timeit using_loop(u) 
10000 loops, best of 3: 61.6 µs per loop 

In [120]: %timeit using_stride(u) 
100000 loops, best of 3: 11.9 µs per loop 

= 10 ** 3 using_strideが速く28Xです:

In [122]: %timeit using_loop(u) 
1000 loops, best of 3: 636 µs per loop 

In [123]: %timeit using_stride(u) 
10000 loops, best of 3: 22.4 µs per loop 
+0

これはどのようなパフォーマンスですか? – Chiel

+0

かなりクールです。改善の余地はもう見えますか? – Chiel

+0

私のpythonはあなたのストライドの例について語っています。最も遅い実行は最速よりも6.84倍長くなりました。これは、中間結果がキャッシュされていることを意味する可能性があります。 100000回のループ、最高3回:ループあたり9.66μs。これは結果を疑わしいものにします – Chiel

関連する問題