探索Numpy的通用函数
1 数组的运算
In[1]: x = np.arange(4)
print("x =", x)
print("x + 5 =", x + 5)
print("x - 5 =", x - 5)
print("x * 2 =", x * 2)
print("x / 2 =", x / 2)
print("x // 2 =", x // 2) # floor division
x = [0 1 2 3]
x + 5 = [5 6 7 8]
x - 5 = [-5 -4 -3 -2]
x * 2 = [0 2 4 6]
x / 2 = [ 0. 0.5 1. 1.5]
x // 2 = [0 0 1 1]
表 Numpy实现的算数运算符
Operator | 对应的通用函数 | 描述 |
---|---|---|
+ |
np.add |
加法运算 (e.g., 1 + 1 = 2 ) |
- |
np.subtract |
减法运算 (e.g., 3 - 2 = 1 ) |
- |
np.negative |
负数运算 (e.g., -2 ) |
* |
np.multiply |
乘法运算 (e.g., 2 * 3 = 6 ) |
/ |
np.divide |
除法运算 (e.g., 3 / 2 = 1.5 ) |
// |
np.floor_divide |
地板除法运算 (e.g., 3 // 2 = 1 ) |
** |
np.power |
指数运算(e.g., 2 ** 3 = 8 ) |
% |
np.mod |
模/余数 (e.g., 9 % 4 = 1 ) |
2 绝对值
In[2]: x = np.array([-2, -1, 0, 1, 2])
abs(x)
Out[2]: array([2, 1, 0, 1, 2])
对应的Numpy通用函数是np.absolute
,该函数也可以用别名np.abs
来访问:
In[3]: np.absolute(x)
Out[3]: array([2, 1, 0, 1, 2])
In[4]: np.abs(x)
Out[4]: array([2, 1, 0, 1, 2])
这个通用函数也可以处理复数。当处理复数时,返回的是该复数的模(magnitude)
In[5]: x = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j])
np.abs(x)
Out[5]: array([ 5., 5., 2., 1.])
3 三角函数
In[6]: theta = np.linspace(0, np.pi, 3) #array([0. , 1.57079633, 3.14159265])
现在可以对这些值进行一些三角函数计算
In[7]: theta = np.linspace(0, np.pi, 3) #array([0. , 1.57079633, 3.14159265])
print("theta = ", theta)
print("sin(theta) = ", np.sin(theta))
print("cos(theta) = ", np.cos(theta))
print("tan(theta) = ", np.tan(theta))
theta = [ 0. 1.57079633 3.14159265]
sin(theta) = [ 0.00000000e+00 1.00000000e+00 1.22464680e-16]
cos(theta) = [ 1.00000000e+00 6.12323400e-17 -1.00000000e+00]
tan(theta) = [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16]
反三角函数同样可以使用
In[8]: x = [-1, 0, 1]
print("x = ", x)
print("arcsin(x) = ", np.arcsin(x))
print("arccos(x) = ", np.arccos(x))
print("arctan(x) = ", np.arctan(x))
x = [-1, 0, 1]
arcsin(x) = [-1.57079633 0. 1.57079633]
arccos(x) = [ 3.14159265 1.57079633 0. ]
arctan(x) = [-0.78539816 0. 0.78539816]
4 指数和对数
In[9]: x = [1, 2, 3]
print("x =", x)
print("e^x =", np.exp(x))
print("2^x =", np.exp2(x))
print("3^x =", np.power(3, x))
x = [1, 2, 3]
e^x = [ 2.71828183 7.3890561 20.08553692]
2^x = [ 2. 4. 8.]
3^x = [ 3 9 27]
最基本的np.log
给出的是以自然常数e为底的对数
In[10]: x = [1, 2, 4, 10]
print("x =", x)
print("ln(x) =", np.log(x))
print("log2(x) =", np.log2(x))
print("log10(x) =", np.log10(x))
x = [1, 2, 4, 10]
ln(x) = [ 0. 0.69314718 1.38629436 2.30258509]
log2(x) = [ 0. 1. 2. 3.32192809]
log10(x) = [ 0. 0.30103 0.60205999 1. ]
还有一些特殊的版本,对于非常小的输入值可以保持较好的精度
In[11]: x = [0, 0.001, 0.01, 0.1]
print("exp(x) - 1 =", np.expm1(x))
print("log(1 + x) =", np.log1p(x))
exp(x) - 1 = [ 0. 0.0010005 0.01005017 0.10517092]
log(1 + x) = [ 0. 0.0009995 0.00995033 0.09531018]
当x的值很小时,以上函数给出的值比np.log
和np.exp
的计算精度更精确。
高级的通用函数特性
1 指定输出
在进行大量运算时,有时候可以指定一个用于存放运算结果的数组是非常有用的。不同于创建临时数组,你可以用这个特性将计算结果直接写入到你期望的存储位置。所有的通用函数都可以通过out
参数来指定计算结果的存放位置。
In[12]: x = np.arange(5)
y = np.empty(5)
np.multiply(x, 10, out=y)
print(y)
[ 0. 10. 20. 30. 40.]
这个特性也可以被用作数组视图,例如可以将计算结果写入指定数组的每隔一个元素的位置:
In[13]: y = np.zeros(10)
np.power(2, x, out=y[::2])
print(y)
[ 1. 0. 2. 0. 4. 0. 8. 0. 16. 0.]
如果这里写的是 y[::2] = 2 ** x
, 那么结果将是创建一个临时数组,该数组存放的是2 ** x
的结果, 并且接下来会讲这些值复制到 y
数组中。 对于上述例子中比较小的计算量来说,这两种方式的差别并不大。但是对于较大的数组,通过使用 out
参数能够有效节约内存。
2 聚合
二元通用函数有些非常有趣的聚合功能,这些聚合可以直接在对象上计算。例如,如果我们希望用一个特定的运算reduce
一个数组,那么可以用任何通用函数的reduce
方法。一个reduce
方法会对给定的元素和操作重复执行,直到得到单个的结果。
例如,对add通用函数调用reduce
方法会返回数组中所有元素的和:
In[14]: x = np.arange(1,6)
np.add.reduce(x)
Out[14]:15
同样,对multiply
通用函数调用reduce
方法会返回数组中所有元素的乘积:
In[15]: np.multiply.reduce(x)
Out[15]:120
如果需要存储每次计算的中间结果,可以使用accumulate
:
In[16]: np.add.accumulate(x)
Out[16]:array([ 1, 3, 6, 10, 15])
In[17]: np.multiply.accumulate(x)
Out[17]:array([ 1, 2, 6, 24, 120])
3 outer
任何通用函数都可以用outer方法获得两个不同输入数组所有元素对的函数运算结果。
In[18]: x = np.arange(1, 6)
np.multiply.outer(x, x)
Out[18]:array([[ 1, 2, 3, 4, 5],
[ 2, 4, 6, 8, 10],
[ 3, 6, 9, 12, 15],
[ 4, 8, 12, 16, 20],
[ 5, 10, 15, 20, 25]])
result = numpy.multiply.outer(a, b)
- a,b是两个数组,如果a,b是高维数组,函数会自动将其flatten成1维
- a的长度是m,b的长度是n,外积的结果result是 m * n的数组,数组元素为 result[i,j] = a[i] * b [j]
- 计算公式如下 a = [a1, …, am] and b = [ b1, …, bn]
- result=[ [a1b1, a1b2, … ,a1bn] [a2b1, a2b2, … ,a2bn] … [amb1, amb2, … ,ambn] ]
In[18]: x = np.arange(1, 6)
y = np.arange(2, 5)
np.subtract.outer(x, y)
Out[18]:array([[-1, -2, -3],
[ 0, -1, -2],
[ 1, 0, -1],
[ 2, 1, 0],
[ 3, 2, 1]])