Pythonで簡単なユーザー定義関数を定義し、Numpyのndarray形式の配列を引数として渡すと、各要素に対して戻り値を返してくれます。
【Python Code】
import numpy as np # mathモジュールを使い単純な関数を定義 import numpy as np def add_1(x): return x+1 # 関数による計算 xn = np.arange(-5, 6, 1) print(add_1(xn))
【結果】
[-4 -3 -2 -1 0 1 2 3 4 5 6]
このような機能をNumpyのユニバーサル機能といい、この機能を使うことができる関数をユニバーサル関数というそうです。
ところが、関数の中で組み込み関数以外の関数を使うと、エラーとなってしまいます。例では、シグモイド関数をmathモジュールのexp関数を定義するとエラーになってしまいます。
【Python Code】
#Numpyのユニバーサル機能 # mathモジュールを使いシグモイド関数を定義 import numpy as np import math # 関数の定義 def p_sigmoid(x): return 1 / (1+math.exp(-x)) # 関数による計算 xn = np.arange(-5, 6, 1) print(p_sigmoid(xn))
【結果】
TypeError: only size-1 arrays can be converted to Python scalars
そこで、関数の中をmathモジュールではなくNumpyモジュールのexp関数を使うとうまくいきます。
【Python Code】
#Numpyのユニバーサル機能 #Numpyを使いシグモイド関数を定義 import numpy as np #関数の定義 def n_sigmoid(x): return 1 / (1+np.exp(-x)) #関数による計算 xn = np.arange(-5,6,1) print(n_sigmoid(xn))
【結果】
[0.00669285 0.01798621 0.04742587 0.11920292 0.26894142 0.5
0.73105858 0.88079708 0.95257413 0.98201379 0.99330715]
ところが、今度は引数にPythonのリストを引数とすると、またまたエラーになってしまいます。
【Python Code】
#pythonのリストを引数にする xl = list(range(-5,6,1)) print(n_sigmoid(xl))
【結果】
TypeError: bad operand type for unary -: ‘list’
この場合、Numpyのvectorize関数を使い、関数をベクトル化することができます。
【Python Code】
#numpyのvectorize関数を使用 v_sigmoid = np.vectorize(p_sigmoid) print(v_sigmoid(xl)) v_sigmoid = np.vectorize(n_sigmoid) print(v_sigmoid(xl))
【結果】
[0.00669285 0.01798621 0.04742587 0.11920292 0.26894142 0.5
0.73105858 0.88079708 0.95257413 0.98201379 0.99330715]
[0.00669285 0.01798621 0.04742587 0.11920292 0.26894142 0.5
0.73105858 0.88079708 0.95257413 0.98201379 0.99330715]
同じ答えが返ってきてうまくいっているようです。このようにvectorize関数を使うと、さまざまな関数をユニバーサル関数に変換することができます。
コメント