1.前言

通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数,那什么是元素级的运算呢?其实在我看来就是这里的函数对数组中的每一个元素值作用然后产生新的元素值,返回新的元素值组成的数组。你可以将其看做简单函数(接受一个或者多个标量值,并产生一个或者多个标量值)的矢量化包装器。下面我们看一个简单的例子:

import numpy as np
array = np.arange(4).reshape((2,2))
print("-----源数据-----")
print(array)
print("-----exp()通用函数作用-----")
array_exp = np.exp(array)
print(array_exp)
-----源数据-----
[[0 1]
[2 3]]
-----exp()通用函数作用-----
[[ 1. 2.71828183]
[ 7.3890561 20.08553692]]

我们需要注意:我们的exp()操作对源数组中的每个元素都进行了

的指数操作,这就很好的说明了我们的通用函数是一种对ndarray中的数据执行元素级运算的函数;

我们大概知道在Python中有一个内置模块math模块,这个模块中包含了一些基本的一些数学运算,其中就有math.exp()。我们知道对于深度学习来说有一个很重要的激活函数sigmoid函数,那么为什么我们没有使用math.exp()来计算sigmoid函数呢?其实理由很简单,我们的math模块是Python内置的模块,他只能对标量进行操作(当然即使是list数据类型也不行)。但是对于我们的深度学习来说,我们常用大量的矩阵运算来矢量化数据。所以Python的内置模块math远远不能满足我们的需求。所以我们在深度学习中才需要使用Numpy中的exp通用函数,我们不仅能传递数组给他进行元素级的运算,而且我们也可以传入标量,比math模块提供的exp更加高效。

2.通用函数的分类

通用函数(ufunc)有两种类别:一元(unary)ufunc,他们接受一个数组。返回一个结果数组,当然也能返回两个数组(modf函数),但是这种的不是很常见;

二元(binary)ufunc,他们接受两个数组,并返回一个结果数组。一元(unary)ufunc二元(binary)ufunc

一元ufunc中的第一个是abs与fabs他们有什么区别呢?

import numpy as np
print('-----abs-----')
a = np.abs([-1,-2,-3])
print(a.dtype)
a = np.abs([-1.2,-2.2,-3.3])
print(a.dtype)
a = np.abs(3+4j)
print(a.dtype)
print('-----fabs-----')
f = np.fabs([-1,-2,-3])
print(f.dtype)
f = np.fabs([-1.2,-2.2,-3.3])
print(f.dtype)
f = np.fabs(3+4j)
print(f.dtype)
-----abs-----
int32
float64
float64
-----fabs-----
float64
float64
Traceback (most recent call last):
File "G:/Python源码/numpy_test/numpy_test.py", line 1087, in 
f = np.fabs(3+4j)
TypeError: ufunc 'fabs' not supported for the input types, and the inputs
could not be safely coerced to any supported types according to the
casting rule ''safe''从上面代码可以看出:
1.abs和fabs都是取绝对值的函数。对于fabs函数来说。如果数据可以转换成float的话,他会将数据转换成float类型,然后去绝对值。当然如果不能转换就会抛出异常。
2.还有一点需要注意的就是fabs函数是不能去操作复数的。而abs可以处理复数。
import numpy as np
x = np.random.randn(8)
y = np.random.randn(8)
print(x)
print(y)
print('----------')
array = np.maximum(x,y)
print(array)
[ 2.39382031 0.64527799 1.01170366 -0.07116423 0.40962236 -0.63333263
-0.98736115 -0.67162906]
[ 0.59509196 -0.30740723 -1.59124219 -0.60960202 0.64756039 2.35825079
-0.80191374 0.4045955 ]
----------
[ 2.39382031 0.64527799 1.01170366 -0.07116423 0.64756039 2.35825079
-0.80191374 0.4045955 ]
还有一种不是很常见的ufunc,他能够返回多个数组。modf就是一个例子,他是python内置函数divmod的矢量化版本,用于浮点数数组的小数和整数部分。
import numpy as np
array = np.random.randn(7)*5
print(array)
print('----------')
array = np.modf(array)
print(type(array))
print(array)
[ 7.3704017 -14.69991603 -2.88312289 -3.171596 5.99889683
-4.96691054 2.305141 ]
----------
(array([ 0.3704017 , -0.69991603, -0.88312289, -0.171596 , 0.99889683,
-0.96691054, 0.305141 ]), array([ 7., -14., -2., -3., 5.,