1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

numpy.vectorizeの使い方と実行の速さについて

Posted at

やりたいこと

PythonのNumpyを用いて,行列計算を行いたいが,これらはnumpy同士の*, + , -, / numpy.dotなどを使用しないと計算速度がむしろ,落ちいてしまう.
しかし,実際には,行列の各要素に複雑な計算を代入していきたいことがよくある.その時のために,np.vetorizeなるものがあるが,それの使い方と速さを検証していきたい

##  今回の使う環境
import sys
import numpy as np
print("PythonのVerson:", sys.version)
print("NumpyのVersion:", np.__version__)
PythonのVerson: 3.5.3 |Anaconda custom (64-bit)| (default, Mar  6 2017, 12:15:08) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
NumpyのVersion: 1.15.2

np.vectoraizeの使い方

行列$A = (a){i, j}$に対して,$a{i, j} = a_{i, j} + 1$のような操作を行いたい場合は

A = A + 1などで十分である.

間違っても

for i in range(A.shape[0]):
    for j in range(A.shape[1]):
        A[i, j] = A[i, j] + 1

というようにしてはいけない.

しかし行列$A = (a)_{i, j}$に対して,以下のような複雑な操作を行いたい場合は,例えば,

for i in range(A.shape[0]):
    for j in range(A.shape[1]):
        while A[i, j] < 100:
          A[i, j] *= 2

のような操作を行いたいとする

その場合は,

def f(x):
    while x < 100:
        x *= 2
    
    return x

vf = np.vectorize(f)
A = np.random.random((1000, 1000))

そして,使い方は下のように,なる.書き方としてはとても簡潔であるように感じる.
ついでに,実行時間も計算してみる.

%timeit vf(A)
1 loop, best of 3: 1.49 s per loop

また,通常の書き方もやってみて,実行時間も計測してみる.

def loop():
    A = np.random.random((1000, 1000))
    for i in range(A.shape[0]):
        for j in range(A.shape[1]):
            A[i, j] = f(A[i, j])
%timeit loop()
1 loop, best of 3: 650 ms per loop

実行してみたら,普通に書いた方が実行時間が早かった!vectorizeの方が早いと思っていただけに少しショックである.
また理由がよくわからない.

1
3
0

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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?