矩阵和向量积
文章目录
前言
Numpy 定义了 matrix 类型,使用该 matrix 类型创建的是矩阵对象,它们的加减乘除运算缺省采用矩阵方式计算,因此用法和Matlab十分类似。但是由于 NumPy 中同时存在 ndarray 和 matrix 对象,因此用户很容易将两者弄混。这有违 Python 的“显式优于隐式”的原则,因此官方并不推荐在程序中使用 matrix。在这里,我们仍然用 ndarray 来介绍。
numpy matrix 与ndarray的区别
1.ndarray 可以是任意维数 mat只能是2维的;
2.矩阵乘法
3.matrix 和 array 都可以通过objects后面加.T 得到其转置。但是 matrix objects 还可以在后面加 .H f得到共轭矩阵, 加 .I 得到逆矩阵。
4.** 运算符的作用也不一样 :因为a是个matrix,所以a ** 2返回的是a*a,相当于矩阵相乘。而c是array,c**2相当于,c中的元素逐个求平方
5.numpy 中的array与numpy中的matrix的最大的不同是,在做归约运算时,array的维数会发生变化,但matrix总是保持为2维。例如下面求平均值的运算
一、矩阵和向量积
矩阵的定义、矩阵的加法、矩阵的数乘、矩阵的转置与二维数组完全一致,不再进行说明,但矩阵的乘法有不同的表示。
numpy.dot(a, b[, out])计算两个矩阵的乘积,如果是一维数组则是它们的内积。
代码如下(示例):
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([6, 7, 8, 9, 10])
z = np.dot(x, y)
print(z) # 130
x = np.array([[1, 2, 3], [3, 4, 5], [5, 6, 7]])
print(x)
'''
[[1 2 3]
[3 4 5]
[5 6 7]]
'''
y = np.array([[5, 4, 2], [1, 7, 9], [0, 4, 5]])
print(y)
# [[5 4 2]
# [1 7 9]
# [0 4 5]]
z = np.dot(x, y)
print(z)
'''
[[ 7 30 35]
[19 60 67]
[31 90 99]]
'''
z = np.dot(y, x)
print(z)
'''
[[ 27 38 49]
[ 67 84 101]
[ 37 46 55]]
'''
注意:在线性代数里面讲的维数和数组的维数不同,如线代中提到的n维行向量在 Numpy 中是一维数组,而线性代数中的n维列向量在 Numpy 中是一个shape为(n, 1)的二维数组。
二、矩阵特征值与特征向量
numpy.linalg.eig(a) 计算方阵的特征值和特征向量。
numpy.linalg.eigvals(a) 计算方阵的特征值。
【例1】求方阵的特征值特征向量
代码如下(示例):
import numpy as np
x = np.diag((1, 3, 5))
print(x)
'''
[[1 0 0]
[0 3 0]
[0 0 5]]
'''
print(np.linalg.eigvals(x))
# [1. 3. 5.]
a, b = np.linalg.eig(x)
# 特征值保存在a中,特征向量保存在b中
print(a)
# [1. 3. 5.]
print(b)
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
# 检验特征值与特征向量是否正确
for i in range(3):
if np.allclose(a[i] * b[:, i], np.dot(x, b[:, i])):
#numpy判断两个向量是否相近-numpy.allclose,在公差范围内就为true
print('Right')
else:
print('Error')
# Right
# Right
# Right
【例2】判断对称阵是否为正定阵(特征值是否全部为正)。
代码如下(示例):
import numpy as np
A = np.arange(16).reshape(4, 4)
print(A)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]]
A = A + A.T # 将方阵转换成对称阵
print(A)
# [[ 0 5 10 15]
# [ 5 10 15 20]
# [10 15 20 25]
# [15 20 25 30]]
B = np.linalg.eigvals(A) # 求A的特征值
print(B)
# [ 6.74165739e+01 -7.41657387e+00 1.82694656e-15 -1.72637110e-15]
# 判断是不是所有的特征值都大于0,用到了all函数,显然对称阵A不是正定的
if np.all(B > 0):
print('Yes')
else:
print('No')
# No
三、矩阵分解
3.1 奇异值分解
有关奇异值分解的原理:奇异值分解(SVD)及其应用
u, s, v = numpy.linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)奇异值分解
a 是一个形如(M,N)矩阵
full_matrices的取值是为False或者True,默认值为True,这时u的大小为(M,M),v的大小为(N,N)。否则u的大小为(M,K),v的大小为(K,N) ,K=min(M,N)。
compute_uv的取值是为False或者True,默认值为True,表示计算u,s,v。为False的时候只计算s。
总共有三个返回值u,s,v,u大小为(M,M),s大小为(M,N),v大小为(N,N),a = usv。
其中s是对矩阵a的奇异值分解。s除了对角元素不为0,其他元素都为0,并且对角元素从大到小排列。s中有n个奇异值,一般排在后面的比较接近0,所以仅保留比较大的r个奇异值。
注:Numpy中返回的v是通常所谓奇异值分解a=usv’中v的转置。
【例1】
代码如下(示例):
import numpy as np
A = np.array([[4, 11, 14], [8, 7, -2]])
print(A)
# [[ 4 11 14]
# [ 8 7 -2]]
u, s, vh = np.linalg.svd(A, full_matrices=False)
print(u.shape) # (2, 2)