2015-09-15 19 views
7

私はPythonには新しく、いくつかの基本的な信号処理をしようとしていますが、パフォーマンス上の問題が深刻です。ベクトル化された方法でこれを行うためのpythonのトリックはありますか?基本的には1次フィルタを実装しようとしていますが、フィルタの特性が1つのサンプルから次のサンプルに変わることがあります。それが1つのフィルタであれば、numpy.signal.lfilter()を使用しますが、それはやや難解です。numpy配列の高速反復

#filter state 
state = 0 

#perform filtering 
for sample in amplitude: 
    if(sample == 1.0): #attack filter 
     sample = (1.0 - att_coeff) * sample + att_coeff * state 
    else: #release filter 
     sample = (1.0 - rel_coeff) * sample + rel_coeff * state 

    state = sample 

答えて

0

各エントリは前のエントリを必要とし、あなたは現在のエントリを計算することができます前に、前のエントリを計算する必要があります。ここでは非常にゆっくり行くのコードの抜粋です。したがって、各エントリは連続して計算されなければならず、ベクトル化された(すなわちマップされた並列の)方法では実行できません。

7

cython,numbaまたはpythranの中のPythonからネイティブコードへの変換を使用することを検討できます。例えば

、はtimeitを使用して、元のコードを実行することは、私を与える:

$ python -m timeit -s 'from co import co; import numpy as np; a = np.random.random(100000)' 'co(a, .5, .7)' 
10 loops, best of 3: 120 msec per loop 

pythranでそれに注釈を付けるが、のように:

#pythran export co(float[], float, float) 
def co(amplitude, att_coeff, rel_coeff): 
    #filter state 
    state = 0 

    #perform filtering 
    for sample in amplitude: 
     if(sample == 1.0): #attack filter 
      state = (1.0 - att_coeff) * sample + att_coeff * state 
     else: #release filter 
      state = (1.0 - rel_coeff) * sample + rel_coeff * state 
    return state 

$ pythran co.py 

でそれをコンパイルします私に与える:

$ python -m timeit -s 'from co import co; import numpy as np; a = np.random.random(100000)' 'co(a, .5, .7)' 

1000年のループ、3の最高:おおよそのx 470のスピードアップだループあたり253マイクロ秒

は、私がNumbaとcythonが同様のスピードアップを与えることを期待して!

関連する問題