此文章的需求来自:逻辑回归的算法实现,numpy.frompyfunc()函数的使用
1.什么是函数的向量化
1.1函数的一般使用
我们有如下的一个自定义函数
def magic(a, b):
if a > b:
return a + b
else:
return a - b
使用时我们只能单变量传入调用
a = 1
b = 2
ret = magic(a,b)
1.2 函数的向量化需求
现有有个需求:
A=[1,2,3]
B=[4,5,6]
想通过magic函数计算A和B对应的俩元素,并将A和B都计算完。
如果还是老方法的话,只能是:
Y = []
Y.append(magic(A[0], B[0]))
Y.append(magic(A[1], B[1]))
Y.append(magic(A[2], B[2]))
是否可以直接将A和B作为magic入参,直接计算得到结果向量Y:
即 Y = magic(A, B)
这种方法就是函数的向量化~~~~~~
numpy.frompyfunc和numpy.vectorize,实现了函数的向量化,详见下面代码示例。
2.函数向量化的5种方法
2.1直接上code
# -*- coding: utf-8 -*-
"""
@author: 蔚蓝的天空TOM
Talk is cheap, show me the code
Aim:实现函数的向量化
"""
from math import exp
import numpy as np
#自定义函数sigmoid function
def tom_sigmoid(x):
return 1.0 / (1 + exp(-1 * x))
#方法1:for element in x
def tom_for():
x = [1,2,3]
ret = []
for element in x:
ret.append(tom_sigmoid(element))
print(ret)
#[0.7310585786300049, 0.8807970779778823, 0.9525741268224334]
#方法2:[f(x) for x in X]
def tom_np_array():
x = [1,2,3]
ret = [tom_sigmoid(e) for e in x]
print(ret)
#[ 0.73105858 0.88079708 0.95257413]
#方法3:function + np.frompyfunc()
def tom_np_frompyfunc():
x = [1,2,3] #<class 'numpy.ndarray'>
tom_sigmoid_func = np.frompyfunc(tom_sigmoid, 1, 1)
ret = tom_sigmoid_func(x) #<class 'numpy.ndarray'>
print(ret)
#[0.7310585786300049 0.8807970779778823 0.9525741268224334]
#方法5:np.vectorize()
def tom_np_vectorize():
x = [1,2,3] #<class 'numpy.ndarray'>
tom_sigmoid_vec = np.vectorize(tom_sigmoid)
ret = tom_sigmoid_vec(x)
print(ret)
#[ 0.73105858 0.88079708 0.95257413]
if __name__=='__main__':
tom_for()
tom_np_array()
tom_np_frompyfunc()
tom_np_vectorize()
新增加一个方法:如果函数中有非向量参数时,用function+np.frompyfunc可能无法实现次函数的向量化,但是可以使用lambda +np.frompyfunc实现此类函数的向量化
from math import exp
import numpy as np
#方法4:lambda + np.frompyfunc()
x = [1,2,3] #<class 'numpy.ndarray'>
k = 1
tom_sigmoid_efunc = lambda x:1.0 / (1 + exp(-1 * x))*k
tom_sigmoid_func = np.frompyfunc(tom_sigmoid_efunc, 1, 1)
ret = tom_sigmoid_func(x) #<class 'numpy.ndarray'>
print(ret)
#[0.7310585786300049 0.8807970779778823 0.9525741268224334]
新增加一个方法:使用function/lambda + np.frompyfunc函数也可以实现函数的向量化
# -*- coding: utf-8 -*-
"""
@author: 蔚蓝的天空Tom
Aim:使用function/lambda+map实现函数的向量化
"""
#funcion + map
def square(x):
return x^2
a = [1,2,3,4]
ret = list(map(square, a))
print(ret) #[3, 0, 1, 6]
#lambda + map
a = [1,2,3,4]
ret = list(map(lambda x:x^2, a))
print(ret) #[3, 0, 1, 6]
#多参数形式
a = [1,2,3,4]
b = [9,8,7,6]
ret = list(map(lambda x,y:x*y, a, b))
print(ret) #[9, 16, 21, 24]
#含有固定参数a
a = [1,2,3,4]
b = [9,8,7,6]
alpha = 0.1
ret = list(map(lambda x,y:float('%2.f'%(alpha*x*y)), a, b))
print(ret) #[1.0, 2.0, 2.0, 2.0]
2.2运行结果
runfile('C:/Users/Administrator/np_frompyfunc.py', wdir='C:/Users/Administrator')
[0.7310585786300049, 0.8807970779778823, 0.9525741268224334]
[ 0.73105858 0.88079708 0.95257413]
[0.7310585786300049 0.8807970779778823 0.9525741268224334]
[ 0.73105858 0.88079708 0.95257413]
3.应用示例
3.1代码
# -*- coding: utf-8 -*-
"""
@author: 蔚蓝的天空Tom
Aim:一网打尽函数的向量化操作
"""
import numpy
#sigmoid function
def sigmoid(z):
return 1/(1+numpy.exp(-1*z))
#sigmoid function for matrix or array or list
def sigmoid_for_m(Z):
fin = 1
fout = 1
sigmoid_func = numpy.frompyfunc(sigmoid, fin, fout)
return sigmoid_func(Z)
if __name__=='__main__':
z = [1,2,3]
Y1 = sigmoid(z)
Y2 = sigmoid_for_m(z)
#dump type
z_type = type(z)
Y1_type = type(Y1)
Y2_type = type(Y2)
print('z_type:',z_type)
print('Y1_type:',Y1_type)
print('Y2_type:',Y2_type)
#dump value
print('z:',z)
print('sigmoid(z):',Y1)
print('sigmoid_for_m(z):',Y2)
3.2运行结果
enjoy it~
(end)