今日,分享点Python学习小记,利用Python实现以下目的:
(1)判定是否为方阵
矩阵的本质就是映射。对于一个m×n的矩阵A,y=Ax的作用是将向量从n维原始空间中的x坐标位置,映射到m维目标空间中的y坐标位置,这是正向映射的结果。如果用y去反推x的过程,被称为逆映射或逆问题。表征逆映射的矩阵为矩阵A的逆矩阵。
对于“矮胖”矩阵(即m<n)压缩空间,不存在逆映射,也即不存在逆矩阵;
对于“高瘦”矩阵(即m>n)不存在逆映射,目标空间无法全覆盖,即也不存在逆矩阵。
方阵是逆映射存在必要不充分条件。
(2) 判定是否矩阵可逆
在(1)的基础上,已知矩阵A为方阵,判定矩阵A是否可逆最简单的方法——求秩。如果秩小于行数或列数,那么该矩阵不可逆;如果秩等于行数或列数,则该矩阵可逆。
(3) 求解特征数和特征向量
该问题建立在矩阵为方阵的基础上。
整个编程思路为:
进行矩阵计算,需要numpy和scipy第三方库的支持。首先,引入第三方库:
import numpy as npfrom scipy import linalg
python输入矩阵方式有(以三阶单位阵为例):
(1)
A = np.matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
(2)
A = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
python输入矩阵的体验确实不如Matlab,如果你只是单纯想体验python求解逆矩阵或求特征值和特征向量的过程,不想自己输入矩阵的话,我们可以利用python生成随机矩阵,我这里设置的随机行列数为3~5。
import randomA = np.random.rand(random.randint(3,5), random.randint(3,5))print(A)row = A.shape[0]col = A.shape[1]print("这是一个 {0} 行 {1} 列的矩阵。".format(row,col))
利用print语句打印出生成的随机矩阵,利用shape语句计算随机矩阵的行和列,接下来需要判定这个随机矩阵A是否为方阵,就要引入if-else条件语句。
#若A不是方阵if row != col: print("该矩阵不存在可逆矩阵。")#若A为方阵else: 进行特征值和特征向量计算
计算特征值和特征向量的命令为scipy库的linalg语句。一个方阵有几行(列)意味着有几个特征值以及对应的特征向量。
print("该矩阵有 {} 个特征值,分别为:".format(row))# 求解特征值和特征向量evalue, evector = linalg.eig(A)for i in range(row): print("{0} 对应特征向量为 {1}".format(evalue[i], evector[i]))
然后,进行判定矩阵是否可逆,求秩的python语句为np.linalg.matrix_rank。接着根据秩数与行(列)数的关系,进行进一步的判定,这里又要用到if-else语句。
rank = np.linalg.matrix_rank(A)if rank != row: print("该矩阵不存在可逆矩阵。")else: #求逆矩阵 Ainv = linalg.inv(A) print("该矩阵的逆矩阵为:{}".format(Ainv)) #验证逆矩阵 print(np.dot(A, Ainv)
如果你不想使用随机矩阵,想自己输入矩阵分析也是可以实现的。若单纯使用input语句在命令行里输入矩阵,会出现以下情况:
可见,通过input语句输入的数据为str(字符串)格式,无法判别矩阵的行数和列数,也就不能进行下一步的分析。同时,我们也可以看出list(列表)格式,便于生成矩阵,而且在命令行中不需要输入np.matrix或np.array的前缀。只要确保输入的数据为list格式,就可以进行接下来的分析。我们可以用下面的语句实现这个想法。
import astA = ast.literal_eval(input('请输入矩阵(按行输入,逗号隔开):')分析的代码
如果只是简单把上面的代码进行一个整合,程序确实可以正常的运行,但是每当你想去计算一个矩阵时,都要重新进行调试状态,重新在cmd命令行输入语句,我们可以给整个代码设计一个循环,由我们自己决定什么时候退出程序,这里就可以使用while命令行,所以整个代码如下:
import numpy as npfrom scipy import linalgimport randomimport ast#import timewhile True: content = input('输入指令(输入"m"自行输入矩阵;输入"r"生成随机矩阵;输入"q"退出程序): ') if content == "q": break elif content == "r": A = np.random.rand(random.randint(3,5), random.randint(3,5)) print(A) row = A.shape[0] col = A.shape[1] print("这是一个 {0} 行 {1} 列的矩阵".format(row,col)) if row != col: print("该矩阵不存在可逆矩阵") else: print("该矩阵有 {} 个特征值,分别为:".format(row)) evalue, evector = linalg.eig(A) for i in range(row): print("{0} 对应特征向量为 {1}".format(evalue[i],evector[i])) rank = np.linalg.matrix_rank(A) if rank != row: print("该矩阵不存在可逆矩阵.") else: Ainv = linalg.inv(A) print("该矩阵的逆矩阵为: {}".format(Ainv)) print(np.dot(A, Ainv)) elif content == "m": A = ast.literal_eval(input('请输入矩阵(按行输入,逗号隔开):')) A = np.matrix(A) row = A.shape[0] col = A.shape[1] if row != col: print("该矩阵不存在可逆矩阵") else: print("该矩阵有 {} 个特征值,分别为:".format(row)) evalue, evector = linalg.eig(A) for i in range(row): print("{0} 对应特征向量为 {1}".format(evalue[i], evector[i])) rank = np.linalg.matrix_rank(A) if rank != row: print("该矩阵不存在可逆矩阵.") else: Ainv = linalg.inv(A) print("该矩阵的逆矩阵为: {}".format(Ainv)) print(np.dot(A, Ainv)) #time.sleep(2)
最后,可以根据自己需要决定是否引入time模块,因为这个过程不涉及爬虫的环节,所有有无time模块都可以,并不影响程序运行。
参考书:
[1] 张雨萌.机器学习线性代数基础(Python语言描述)
[2]小甲鱼.零基础入门学习Python(第一版)
[3]小甲鱼.零基础入门学习Python(第二版)