スライドショー

【NumPy入門】np.vectorizeでPython関数を簡単にユニバーサル関数化!

こんにちは!インストラクターのフクロウです!NumPyにはホントにたくさんの関数があります。これを全部使いこなすのは少し難しいですし、NumPyの機能だけでは実装できない処理もあるはずです。

そんなときに役に立つのがnp.vectorize関数Pythonの関数を簡単にNumPyの関数にしてくれます!この記事で使い方を学んで使ってみてください!

np.vectorizeの使い方

np.vectorizeの基本的な使い方

np.vectorizeは、Pythonの関数を配列に適用できるように変換する関数です。NumPyにおいて、配列のすべての要素に一括で処理を適用できる関数のことをユニバーサル関数といいます。

np.vectorizeでユニバーサル関数にできる関数は、スカラー値や文字列が引数になっているものです。では、Pythonで実装したsigmoid関数を、np.vectorizeでユニバーサル関数化してみましょう。

import numpy as np
import math

# ①ターゲットのPython関数
def py_sigmoid(x):
    return 1/ (1+math.exp(-x))

# ②forループでユニバーサル関数っぽくしたもの
def vpy_sigmoid(X):
    result = np.zeros_like(X)
    for i in range(len(X)):
        result[i] = py_sigmoid(X[i])
    return result

# ③np.vectorizeでユニバーサル関数を作ったもの
vsigmoid = np.vectorize(py_sigmoid)

# ④NumPy関数で作ったユニバーサル関数
def np_sigmoid(x):
    return 1/ (1+np.exp(-x))

①はスカラーを受け取って、スカラーを返す関数です。

>>> X = np.linspace(-10,10, 10)

>>> py_sigmoid(X)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-a145f0f92b5a> in <module>()
----> 1 py_sigmoid(X)

<ipython-input-2-bcf4ceeeadd2> in py_sigmoid(x)
      1 def py_sigmoid(x):
----> 2     return 1/ (1+math.exp(-x))
      3 
      4 def vpy_sigmoid(X):
      5     result = np.zeros_like(X)

TypeError: only size-1 arrays can be converted to Python scalars

この関数を配列のすべての要素に適用するには、普通に考えるとfor文を使うことになります。それが②ですが、np.vectorizeを使うと一行で再現することができます。

では、これらの関数がちゃんと動作するか見てみましょう。

>>> vpy_sigmoid(X)

array([4.53978687e-05, 4.18766684e-04, 3.85103236e-03, 3.44451957e-02,
       2.47663801e-01, 7.52336199e-01, 9.65554804e-01, 9.96148968e-01,
       9.99581233e-01, 9.99954602e-01])

>>> vsigmoid(X)

array([4.53978687e-05, 4.18766684e-04, 3.85103236e-03, 3.44451957e-02,
       2.47663801e-01, 7.52336199e-01, 9.65554804e-01, 9.96148968e-01,
       9.99581233e-01, 9.99954602e-01])

>>> np_sigmoid(X)

array([4.53978687e-05, 4.18766684e-04, 3.85103236e-03, 3.44451957e-02,
       2.47663801e-01, 7.52336199e-01, 9.65554804e-01, 9.96148968e-01,
       9.99581233e-01, 9.99954602e-01])

どの書き方の関数でも、同様にすべての要素にsigmoid関数の計算ができていることがわかりますね。今回はsigmoidなのでNumPyの機能だけでキレイに書き下せますが、難しい場合には非常に便利ですね。

何よりfor文を書かずにNumPyっぽくプログラムがかけるのがいいですね!

np.vectorizeの速度比較

さて、Pythonの関数を気軽にユニバーサル関数にできるnp.vectorizeですが、実行速度はどうでしょうか。ipythonやjupyterなどの環境で、プログラムの実行時間を測る%timeit機能を使って測ってみましょう!

sample = np.linspace(-100,100, 1000)

%timeit vpy_sigmoid(sample)
%timeit vsigmoid(sample)
%timeit np_sigmoid(sample)
[Output]
357 µs ± 2.84 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
244 µs ± 2.73 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
15.3 µs ± 170 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

for文で書いたvpy_sigmoidよりは、速度があまり必要でない関数やNumPyで書くのが難しい関数はnp.vectorizeで書くと良さそうです。

まとめ

この記事では、Python関数を簡単にNumPyのユニバーサル関数にする機能、np.vectorize関数を紹介しました。NumPyの関数は独特なので、最初から使いこなすのは難しいかもしれません。

そんなとき、np.vectorize関数を使うことで、手軽に欲しい機能が実装できます!簡単なので是非試して見てくださいね!

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

フクロウ

フクロウ

第一言語はPythonです。
皆さんRustやりましょう。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説