1.5. 数学运算#
本节将对创建的高维数组进行一些数学运算,包括一元函数、二元函数、统计函数以及线性代数。这些运算操作大部分都比较直观,通过函数名或数学运算符的名字,我们就可以知道其要进行的数学计算。
Show code cell content
import numpy as np
在正式开始前,我们先生成数组 x
、 y
和 z
用作演示练习使用。
x = np.array([1,2,3,4])
y = np.array([-1.2,1.4,1.5,1.7])
z = np.array([-1.2,1.4,1.5,1.7])
一元函数#
一元函数对一个数组执行元素级运算。下面以对数 \(\log\) 和取整两个计算来演示 NumPy 的一元运算,其他运算可参考其官方文档。
对数#
对数函数是数学中的一种常见函数,如果 \(a^x=N\),那么 \(x = \log_{a} N\),其中 \(a\)叫做底数,\(N\) 叫真数。通常以 10
为底的对数叫做常用对数,以 \(e\) 为底的对数称为自然对数。
np.log()
是以 \(e\) 为底的自然对数。
np.log(x)
array([0. , 0.69314718, 1.09861229, 1.38629436])
np.log10()
对数组中元素求常用对数。
np.log10(x)
array([0. , 0.30103 , 0.47712125, 0.60205999])
取整运算#
np.ceil()
对数组各元素向上取整;np.floor()
对数组中各个元素向下取整;np.rint()
对数组各元素四舍五入取整。
np.floor(z)
array([-2., 1., 1., 1.])
np.rint(z)
array([-1., 1., 2., 2.])
除去以上一元函数,还有以下函数较为常用:
类型 |
函数 |
用途 |
---|---|---|
普通型三角函数 |
[ |
计算正弦函数 |
普通型三角函数 |
[ |
计算余弦函数 |
普通型三角函数 |
[ |
计算正切函数 |
双曲型三角函数 |
[ |
计算双曲正弦函数 |
双曲型三角函数 |
[ |
计算双曲余弦函数 |
双曲型三角函数 |
[ |
计算双曲正切函数 |
指数函数 |
[ |
计算数组各元素的指数值 |
符号函数 |
[ |
计算数组各元素的符号值 |
二元函数#
二元运算是指对两个对象(操作数)进行的运算:给定集合 \(A\),二元函数 \(F\) : \(A\times A\) → \(A\) 称为集合 \(A\) 上的二元运算。需要注意的是,二元运算的运算结果跟两个输入值必须是同种类型的数据。例如,加法的两个操作数都是整数,得到的运算结果也是整数。
简单数学操作#
两个数组的元素加减乘比较直观,使用常用的数学符号即可。
函数 |
含义 |
示例 |
---|---|---|
[ |
对两个数组进行加法运算 |
x+y |
[ |
对两个数组进行减法运算 |
x-y |
[ |
对两个数组进行乘法运算 |
x*y |
[ |
对两个数组进行乘法运算 |
x/y |
下面我们以两个数组元素的加法运算为例:
x / y
array([-0.83333333, 1.42857143, 2. , 2.35294118])
np.fmax
、np.maximum
和 np.fmin
、np.minimum
函数对两个数组进行元素级最大/小值计算。
np.maximum(x,y)
array([1., 2., 3., 4.])
比较操作#
我们可以对两个数组逐元素进行算数比较,产生布尔型数组:
符号 |
含义 |
---|---|
[ |
小于 |
[ |
大于 |
[ |
大于等于 |
[ |
小于等于 |
[ |
等于 |
[ |
不等于 |
Note
需要注意的是,我们常用 =
表示赋值功能,不能用来进行数组的比较。判定数组是否相等时,使用 ==
符号。
下面用一个例子作为示范,使用 ==
对数组 x
, y
元素级进行比较是否相等,相等输出结果 True
,若元素对应不相等,则输出结果 False
。
x==y
array([False, False, False, False])
统计函数#
一元函数和二元函数对数组进行元素级运算,统计函数对高维数组的某个维度(行或列)及整体进行统计运算。
Note
axis
参数用来指定对高维数组的哪个维度(或者说是轴)进行操作,不指定时默认求整体;axis=0
对高维数组的第一个维度进行计算,二维数组的 axis=0
指的是列; axis=1
对高维数组的第二个维度进行计算,二维数组的 axis=1
指的是行。
np_array_2d = np.arange(0, 6).reshape([2,3])
np_array_2d
array([[0, 1, 2],
[3, 4, 5]])
np.sum(np_array_2d, axis = 0)
array([3, 5, 7])
np.sum(np_array_2d)
15
其他统计函数还有:
函数 |
用途 |
---|---|
[ |
求平均值 |
[ |
求和 |
[ |
求最大值 |
[ |
求最小值 |
[ |
求方差 |
[ |
求标准误 |
线性代数#
矩阵与向量的乘积#
dot(a,b)
计算两个数组的点积:
1)如果 a
和 b
都是一维数组,那么点积即为内积(没有共轭);
np.dot(3, 4)
12
np.dot(3j, 4j)
(-12+0j)
2)如果 a
和 b
都是二维数组,np.dot()
等价于矩阵乘法,也可以用 a @ b
来表示;
a = [[1, 0], [0, 1]]
b = [[4, 1], [2, 2]]
np.dot(a, b)
array([[4, 1],
[2, 2]])
3)如果 a
或 b
是标量(维数为 0),那么其点积等价于乘,可以使用 numpy.multiply(a,b)
或 a*b
来表示;
a = 4
b = [[4,1],[2,2]]
np.dot(a,b)
array([[16, 4],
[ 8, 8]])
4)如果a
是一维数组, b
是N
维数组,那么点积是 a
与 b
的最后一个轴的积的和;
a = [3,4,5]
b = [[1,2,3],[4,5,6],[7,8,9]]
np.dot(a,b)
array([54, 66, 78])
5)如果a
是N
维数组, b
是M-d
维数组(M≥2),那么点积为 a
的最后一个轴与 b
的倒数第二条轴的乘机的和:
dot(a,b)[i,j,k,m] = sum(a[i,j,:]*b[k,:,m])
a = [[1,5,7],[2,4,6],[3,6,9],[4,8,10]]
b = [[1,2,3],[4,5,6],[7,8,9]]
np.dot(a,b)
array([[ 70, 83, 96],
[ 60, 72, 84],
[ 90, 108, 126],
[106, 128, 150]])
矩阵特征值#
假设我们有一个 n
阶的矩阵 A
以及一个实数 λ
,使得我们可以找到一个非零向量 x
,满足:\(Ax = \lambda x\),如果能够找到的话,我们就称 λ
是矩阵 A
的特征值,非零向量 x
是矩阵 A
的特征向量。我们可以使用 np.linalg.eig(a)
函数计算方阵的特征值和特征向量。
eigenvalues, eigenvectors = np.linalg.eig(np.diag((1, 2, 3)))
我们还可以使用 np.linalg.eigvals(a)
函数计算一般矩阵的特征值。
与 np.linalg.eig()
函数不同的是, np.linalg.eigvals()
不返回特征向量。
范数(norm)和秩(rank)#
在线性代数中, 范数(norm)是一个表示“长度”概念的函数,为向量空间内的所有向量赋予非零的正长度或大小。
首先,我们生成矩阵 a
用于练习演示:
b = np.arange(9)
a = b.reshape((3,3))
a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
np.linalg.norm(a)
14.2828568570857
在线性代数中,一个矩阵 A
的列秩是 A
的线性独立的纵列的极大数,通常表示为 r(A)
,rk(A)
或 rank A
。
行秩是 A
的线性无关的横行的极大数目。即如果把矩阵看成一个个行向量或者列向量,秩就是这些行向量或者列向量的秩,也就是极大无关组中所含向量的个数。我们可以使用 np.linalg.matrix_rank(A)
函数,使用 SVD 方法计算并返回数组的矩阵秩。
np.linalg.matrix_rank(a)
2
接下来,我们生成一个4维满秩的矩阵 b
,该矩阵的秩与维数相同。
b = np.eye(4)
b
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
解方程与逆#
我们可以使用 np.linalg.solve(a, b)
函数求解线性矩阵方程或线性标量方程组。
a = np.array([[1, 2], [7, 9]])
b = np.array([1, 2])
x = np.linalg.solve(a, b)
x
array([-1., 1.])
根据生成的矩阵中元素,我们可以列出所求解的方程组为 x0+2*x1=1
和 7*x0+9*x1=2
。
设 A
是数域上的一个 n
阶方阵,若在相同数域上存在另一个 n
阶矩 B
,使得: AB=BA=E
。则我们称 B
是 A
的逆矩阵, A
则被称为可逆矩阵。
其中,E
为单位矩阵
我们可以使用 np.linalg.inv(a)
函数对矩阵 a
求逆。
b = np.arange(4) +1
a = b.reshape((2,2))
ainv = np.linalg.inv(a)
ainv
array([[-2. , 1. ],
[ 1.5, -0.5]])