2016-07-05 8 views
7

問題:最適化配列要素シフトのPython/numpyの

私が書かれているデータ解析コードのラインプロファイリングを実行した後、私は、総運転時間の約70%がへの呼び出しに集中していることを見出しました2つの異なる配列操作ルーチン。私は最終的にはリアルタイムでデータを分析したいので、ここでの最適化は大幅に役立ちます。

Matrix Forms

二つの機能は左側にマトリックスを取り、右のフォーム(およびその逆)にそれをもたらします。

私が興味を持っている行列は、現在、N×N個のnumpy配列(Nは偶数)で格納されています。

コード:

私はこれを達成するために、次のコードを書かれている:

# Shifts elements of a vector to the left by the given amount. 
def Vec_shift_L(vec, shift=0): 
    s = vec.size 
    out = np.zeros(s, dtype=complex) 
    out[:s-shift] = vec[shift:] 
    out[s-shift:] = vec[:shift] 
    return out 

# Shifts elements of a vector to the right by the given amount. 
def Vec_shift_R(vec,shift=0): 
    s=vec.size 
    out=np.zeros(s, dtype=complex) 
    out[:shift] = vec[s-shift:] 
    out[shift:] = vec[:s-shift] 
    return out 

# Shifts a matrix from the left form (above) to the right form. 
def OP_Shift(Trace): 
    s = Trace.shape 
    Out = np.zeros(s, dtype=complex) 

    for i in np.arange(s[0]): 
     Out[i,:] = Vec_shift_L(Trace[i,:], (i+s[0]/2) % s[0]) 

    for i in np.arange(s[0]): 
     Out[i,:] = np.flipud(Out[i,:]) 

    return Out 

# Shifts a matrix from the right form (above) to the left form. 
def iOP_Shift(Trace): 
    s = Trace.shape 
    Out = np.zeros(s, dtype=complex) 
    for i in np.arange(s[0]): 
     Out[i,:] = np.flipud(Trace[i,:]) 

    for i in np.arange(s[0]): 
     Out[i,:] = Vec_shift_R(Out[i,:], (i+s[0]/2) % s[0]) 

    return Out 

もともとこれを書いたとき、私はnumpyののロール機能を知らなかったので、私はその中でvec_shift機能を書いていました場所。私の現在のシステムでロールを使用すると、パフォーマンスは〜30%向上しているようです。

さらにこのコードのパフォーマンスを向上させる方法はありますか?

答えて

5

NumPy broadcastingは、ベクトル化されたソリューションに役立ちます。

# Store shape of input array 
s = Trace.shape 

# Store arrays corresponding to row and column indices 
I = np.arange(s[0]) 
J = np.arange(s[1]-1,-1,-1) 

# Store all iterating values in "(i+s[0]/2) % s[0]" as an array 
shifts = (I + s[0]/2)%s[0] 

# Calculate all 2D linear indices corresponding to 2D transformed array 
linear_idx = (((shifts[:,None] + J)%s[1]) + I[:,None]*s[1]) 

# Finally index into input array with indices for final output 
out = np.take(Trace,linear_idx) 
+0

ありがとうございました!私はこのようなエレガントな方法で、互換性のない行列形状の操作を実行できることはわかりませんでした。これはかなり役に立ちます。 :D – DMilden

関連する問題