LoginSignup
45
26

More than 5 years have passed since last update.

Numpyの配列でappendを使うと遅くなる

Last updated at Posted at 2018-09-17

Numpyの配列(ndarray)でappendを使っていますか?

僕は使っています。

append.py
import numpy as np
tmp = np.array([])

#適当なデータ
data = [0,1,2,3,4,5,6,7,8,9]

for datum in data:
    tmp = np.append(tmp, datum)
print(tmp)

結果から言うとNumpyの配列に対してfor文を使って何度も配列を結合する(appendする)処理は重いです。

パフォーマンスを上げるためにはどうしたらよいのか

Numpyの配列(ndarray)をPython標準のlist配列にいったん変換してappendを行い、ループを抜けた後にNumpyの配列に変換するのが一番手っ取り早い方法だと思います。

append.py
import numpy as np
tmp = np.array([])

#適当なデータ
data = [0,1,2,3,4,5,6,7,8,9]

#ここでNumpyの配列をlistに変換
tmp_list = tmp.tolist()

for datum in data:
    tmp_list.append(datum)

#ここでlistからNumpyの配列に変換
tmp = np.asarray(tmp_list)
print(tmp)

追加したのは2行ですが、かなり計算速度は速くなります。
パフォーマンスを上げるために処理を増やすというのは直感に反するかもしれませんが、我が家のオンボロPCだと100MBくらいのデータの処理に数時間かかっていたものが数分で終わるようになりました。listとndarray間の変換のコストがそれほど高くないため実現できます。

遅くなる原因(かもしれない要因)

Numpyは内部をC言語で書いてあるそうなのでNumpyの配列は固定長配列によって実装されていると思われ、Numpyのappendのメソッドが呼び出されるたびに配列に使うメモリの再確保をしているせいで遅いのかなと勝手に予想しています。一方でPythonのlistは可変長配列であるためappendの処理があらかじめ想定されており、相対的にNumpyの配列よりもlistの方がパフォーマンスがあがるのでしょう。

最後に

Pythonの実行速度はかなりコードに依存しているので、よくないパターンを見つけたらできる限り紹介していきたいと思います。

45
26
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
26