LoginSignup
17
16

More than 3 years have passed since last update.

numpyで明示的にループを書くと極端に遅くなる

Last updated at Posted at 2015-07-21

「コンピュータ言語を遅く使ってしまう方法」で述べたように
numpyで明示的にループを書くと極端に遅くなる。
以下は、初心者向けの話です。

それを実験するコードを書きました。

matmul.py
# -*- coding: utf-8 -*-
u"""
行列演算の速度比較
"""

def matmul1(a, b):
    lenI = a.shape[0]
    lenJ = a.shape[1]
    lenK = b.shape[1]
    c = np.zeros((lenI, lenJ))
    for i in range(lenI):
        for j in range(lenJ):
            for k in range(lenK):
                c[i, j] += a[i, k] * b[k, j]
    return c

def matmul2(a, b):
    lenI = a.shape[0]
    lenJ = a.shape[1]
    lenK = b.shape[1]
    c = np.zeros((lenI, lenJ))
    for i in range(lenI):
        for k in range(lenK):
            for j in range(lenJ):
                c[i, j] += a[i, k] * b[k, j]
    return c

import numpy as np
a = np.random.randn(200, 200)
b = np.random.randn(200, 200)
print a.shape

c2 = matmul2(a, b)
print c2

c = matmul1(a, b)
print c

c3 = np.dot(a, b)
print c3

IPythonのコンソールで
このコードを一度実行させて、関数定義を有効にしてから
%timeit を使って比較してみました。
20倍もの差を生じています。

%timeit c2 = matmul2(a, b)
1 loops, best of 3: 7.39 s per loop

%timeit c1 = matmul1(a, b)
1 loops, best of 3: 7.31 s per loop

%timeit c3 =np.dot(a, b)
1000 loops, best of 3: 321 µs per loop

まとめ
 numpyのように行列演算に最適化されたライブラリを使うときには
 行列の要素に個別にアクセスするようなfor文は基本書かないこと。
 numpyのドキュメントを読んで、呼び出すべき関数を調べてください。
 Spyder統合環境の場合[help][Installed Python Modules]から
 numpyのドキュメントが読めます。

NumPy・SciPyによる高速化の実力を見る

関連記事

画像処理で2重ループをなるべく書くな

17
16
4

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
17
16