如何在python中获得矩阵的逆?我自己实现了它,但它是纯 python,我怀疑有更快的模块可以做到这一点。
7 回答
如果您进行矩阵操作,您应该看看numpy 。这是一个主要用C语言编写的模块,比纯python编程要快得多。这是一个如何反转矩阵以及进行其他矩阵操作的示例。
from numpy import matrix
from numpy import linalg
A = matrix( [[1,2,3],[11,12,13],[21,22,23]]) # Creates a matrix.
x = matrix( [[1],[2],[3]] ) # Creates a matrix (like a column vector).
y = matrix( [[1,2,3]] ) # Creates a matrix (like a row vector).
print A.T # Transpose of A.
print A*x # Matrix multiplication of A and x.
print A.I # Inverse of A.
print linalg.solve(A, x) # Solve the linear equation system.
您还可以查看数组模块,当您只需要处理一种数据类型时,它是一种更有效的列表实现。
确保您确实需要反转矩阵。这通常是不必要的,并且可能在数值上不稳定。当大多数人问如何对矩阵求逆时,他们真的很想知道如何求解 Ax = b,其中 A 是矩阵,x 和 b 是向量。使用直接为 x 求解方程 Ax = b 的代码比计算 A 逆然后将逆乘以 B 更有效和更准确。即使您需要为许多 b 值求解 Ax = b,这也不是一个好主意反转 A。如果您必须求解多个 b 值的系统,请保存 A 的 Cholesky 分解,但不要反转它。
请参阅不要反转该矩阵。
遗憾的是,这里再次重复的所选矩阵要么是奇异的,要么是条件差的:
A = matrix( [[1,2,3],[11,12,13],[21,22,23]])
根据定义,A 的逆矩阵乘以矩阵 A 本身必须给出一个单位矩阵。在广受赞誉的解释中选择的 A 并没有做到这一点。事实上,只看倒数就可以看出倒数不能正常工作。看看各个项的大小 - 与原始 A 矩阵的项相比,它们非常非常大......
值得注意的是,人类在选择矩阵示例时经常设法选择奇异矩阵!
我确实对解决方案有疑问,所以进一步研究了它。在ubuntu-kubuntu平台上,debian包numpy没有matrix和linalg子包,所以除了导入numpy,还需要导入scipy。
如果 A 的对角项乘以一个足够大的因子,比如 2,则矩阵很可能不再是奇异的或接近奇异的。所以
A = matrix( [[2,2,3],[11,24,13],[21,22,46]])
变得既不是单数也不是近乎单数,并且该示例给出了有意义的结果...在处理浮点数时,必须注意不可避免的舍入错误的影响。
对于像我这样正在寻找没有pandas
或numpy
参与的纯 Python 解决方案的人,请查看以下 GitHub 项目:https ://github.com/ThomIves/MatrixInverse 。
它慷慨地提供了一个很好的解释,解释了这个过程是如何“在幕后”的。作者很好地描述了分步方法并提供了一些实际示例,所有这些都易于理解。
这只是那里的一个小代码片段,非常简要地说明了该方法(AM
是源矩阵,IM
是相同大小的单位矩阵):
def invert_matrix(AM, IM):
for fd in range(len(AM)):
fdScaler = 1.0 / AM[fd][fd]
for j in range(len(AM)):
AM[fd][j] *= fdScaler
IM[fd][j] *= fdScaler
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
crScaler = AM[i][fd]
for j in range(len(AM)):
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
return IM
但是请务必遵循整件事,您将学到更多,而不仅仅是复制粘贴此代码!顺便说一句,还有一个 Jupyter 笔记本。
希望对某人有所帮助,我个人发现它对于我无法使用任何非标准包的非常特殊的任务(吸收马尔可夫链)非常有用。
Numpy 会适合大多数人,但你也可以在 Sympy 中做矩阵
尝试在http://live.sympy.org/运行这些命令
M = Matrix([[1, 3], [-2, 3]])
M
M**-1
为了好玩,试试M**(1/2)
如果您讨厌 numpy,请取出 RPy 和您的本地 R 副本,并改用它。
(我也会回应让你真的需要反转矩阵。例如,在 R 中,linalg.solve 和 solve() 函数实际上并没有完全反转,因为它是不必要的。)