【机器学习】【Numpy】函数向量化运算的多种方法function/lambda + numpy.frompyfunc()/map和numpy.vectorize()

此文章的需求来自:逻辑回归的算法实现,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)

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值