pythonのループは遅い?

pythonはデータの処理になにかと便利なので重宝していますが、ループ(for)の処理は一般的に遅いと言われています。(このためベクターで処理するのが良いと言われています。)

とはいえ、今まで実感としてはなかったんですが、ちょっとした処理をforループとnumpyで比較してみたら、桁違いの速度だったのでメモを残します。

風向のデータ(0~360°)、1年分(8760h)を16方位にまとめる

これをforループを使って次のように処理しました。8760h×16方位のループになっています。

theta = 360/16
for i in range(8760):          
    for j in range(16):
        angle = theta*j
        if(j==0):
            if ((360 - theta/2 < winddirs[i]) or (winddirs[i] <= angle + theta/2)):
                winddirs[i] = 0.0
                break
        else:
            if ((angle - theta/2 < winddirs[i]) and (winddirs[i] <= angle + theta/2)):
                winddirs[i] = angle
                break

ループ処理としてありがちなパターンですが、これがひたすら遅い。恐ろしく遅い。処理時間はなんと約240秒。処理がなかなか終わらないので、てっきりフリーズしたのかと思うほどです。

そして、NumPyで書き直したのが次のコード。where()を使って8760h分の値をまとめて一気に条件判定して値を更新しています。

theta = 360/16
for j in range(16):
    angle = theta*j
    if(j==0):
        min_angle = 360 - theta/2
        max_angle = theta/2
        winddirs = np.where((min_angle < winddirs)|(winddirs <= max_angle), 0.0, winddirs)
    else:
        min_angle = angle - theta/2
        max_angle = angle + theta/2                
        winddirs = np.where((min_angle < winddirs) & (winddirs <= max_angle), angle, winddirs) 

ステップ数はそれほど変わりませんが、こちらは約0.5秒の爆速で終了します。ループの処理が大幅に減った(16×8760hから16個)のも効いているようですが、それにしてもベクトルをまとめて処理すると速いですよね。

ということで、一般に言われているようにforループ処理が遅いのは確かなようです。基本的に大量のデータはNumpyなどを利用して、まとめて処理するのが良いようです。

動作環境

以下の環境で動作を確認しています。

Windows10 Pro(64bit, 1809)
Python3.7.3

Pocket

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です