いろんなものはつながっている

pythonで時間がかかる処理

numpy.appendは遅い

短時間フーリエ変換を繰り返し行う処理がものすごい遅い。
サンプル数256程度のfftを2万回行うのに1分以上かかる。68秒もかかった。

time()を使って時間を計測したら、遅い原因はフーリエ変換ではなくnumpy.arrayのappendだった。
appendのたびにメモリを確保しているみたい。
appendされた行列のサイズが大きくなっていくごとにappendする時間も増加している。

npappend

sa=400000
duration=1
fftpt=256

w = signal.hamming(fftpt)
sig=np.random.randn(sa)+1j*np.random.randn(sa)
start_idx = 0
fft_result=np.zeros((0,fftpt), 'complex')
elapsed_time_list = []
itrnum=0
start_total = time.time()
while (start_idx + fftpt) < sa:
    start = time.time()
    sig_frame=sig[start_idx:start_idx+fftpt]
    #フーリエ変換   
    fftdt_=np.fft.fft(w * sig_frame)
    #結果をappend
    fftdt_=np.reshape(fftdt_, (1,fftpt))
    fft_result = np.append(fft_result, fftdt_, axis=0)
    start_idx +=20
    itrnum +=1
    #時間計測
    elapsed_time = time.time() - start
    elapsed_time_list.append(elapsed_time)
   
#計測結果
total_elapsed_time = time.time() - start_total
print('平均処理時間:%.f 全処理時間:%.f 処理回数:%d' % \
        (np.average(elapsed_time_list), total_elapsed_time, itrnum))
plt.plot(range(len(elapsed_time_list)), elapsed_time_list)
plt.show()

ここに、list.appendしてから最後にnumpy.array化する方法との速度比較がある。

自分でもやってみる。

空のリストを用意して
fft_result_list=[]
fftの結果をappendしていく
fft_result_list.append(fftdt_)
最後にndarrayに変換
fft_result = np.array(fft_result_list)

時間は、1.49秒だった。
確かに500倍ぐらい早い

また、結果のサイズが最初からわかっている場合は、あらかじめnumpy.arrayの領域を確保して実行したらどうだろうか。

fft_result=np.zeros((total_num, fftpt), ‘complex’)
で領域を確保しておき
fft_result[i,:]=fftdt_
で結果をコピー

時間はリストの場合と同じ、1.49秒だった。

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサード リンク

カテゴリー

スポンサード リンク