Python语言之码农眼中的数学之~矩阵专栏(附Numpy讲解)
小标 2018-08-08 来源 : 阅读 2043 评论 0

摘要:本文主要向大家介绍了Python语言之码农眼中的数学之~矩阵专栏(附Numpy讲解),通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

本文主要向大家介绍了Python语言之码农眼中的数学之~矩阵专栏(附Numpy讲解),通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

2.1.矩阵的定义

矩阵:是一个按照长方阵列排列的复数或实数集合。

通俗讲就是:把数排成m行n列后,然后用中括号把它们括住,这种形式的组合就是矩阵了~ eg:

⎡⎣⎢⎢⎢⎢⎢⎢⎢a11a21a31⋮am1a12a22a32⋮am2a13a23a33⋮am3.........⋱...a1na2na3n⋮amn⎤⎦⎥⎥⎥⎥⎥⎥⎥[a11a12a13...a1na21a22a23...a2na31a32a33...a3n⋮⋮⋮⋱⋮am1am2am3...amn]

比如上面这个示例就是一个m × n的矩阵(m行n列的矩阵),如果m=n那么就叫做n阶方阵,eg:

⎡⎣⎢147258369⎤⎦⎥[123456789]

这个就是3阶方阵

如果回到中学,老师肯定都是通过一次方程组来引入矩阵(逆天的老师是这么讲的):

⎧⎩⎨x1+x2=−12x1−x2=43x1+5x2=−7{x1+x2=−12x1−x2=43x1+5x2=−7 ==> ⎡⎣⎢1231−15⎤⎦⎥[x1x2]=⎡⎣⎢−14−7⎤⎦⎥[112−135][x1x2]=[−14−7]

如果你方程组都忘记怎么解的话...好吧还是说下吧:“比如这题,可以先把x2移到右边,这样x1就等于一个表达式了(x1=-x2-1),然后带入第二个表达式就可以解出x1和x2了,一次的其实两个表达式就可以解出了,剩下的你可以把值带进去验证一下”

2.2.矩阵的运算(含幂运算)

2.2.1.加、减

加减比较简单,就是对应元素相加减 (只有行列都相同的矩阵才可以进行)

就不用麻烦的LaTex一行行打了,咱们用更方便的 NumPy 来演示一下矩阵加法(不懂代码的直接看结果,不影响阅读的)

Numpy有专门的矩阵函数(np.mat),用法和ndarray差不多,我们这边使用经常使用ndarray类型,基础忘记了可以去查看一下:Numpy基础

扩展:矩阵的加法运算满足交换律:A + B = B + A (乘法不行)

In [1]:

import numpy as np

In [2]:

# 创建两个集合A = np.arange(1,10).reshape((3,3))B = np.arange(9).reshape((3,3))print(A)print("-"*5)print(B)

 

[[1 2 3]
[4 5 6]
[7 8 9]]
-----
[[0 1 2]
[3 4 5]
[6 7 8]]

In [3]:

# 加法A + B

Out[3]:

array([[ 1,  3,  5],
      [ 7,  9, 11],
      [13, 15, 17]])

In [4]:

# 和A+B相等B + A

Out[4]:

array([[ 1,  3,  5],
      [ 7,  9, 11],
      [13, 15, 17]])

In [5]:

# 减法A - B

Out[5]:

array([[1, 1, 1],
      [1, 1, 1],
      [1, 1, 1]])

In [6]:

################ 变化来了 ################

In [7]:

# 之前说过 ”只有行列都相同的矩阵才可以进行“ 来验证一下# 创建一个2行3列的矩阵C = np.arange(6).reshape((2,3))D = np.arange(6).reshape((3,2))print(C)print("-"*5)print(D)

 

[[0 1 2]
[3 4 5]]
-----
[[0 1]
[2 3]
[4 5]]

In [8]:

# 2行3列的矩阵 + 3行2列的矩阵C + D # 不同形状的矩阵不能进行加运算

 

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-8-bc97e29f7e31> in <module>()      1 # 2行3列的矩阵 + 3行2列的矩阵----> 2C + D # 不同形状的矩阵不能进行加运算ValueError: operands could not be broadcast together with shapes (2,3) (3,2)

In [9]:

C - D # 不同形状的矩阵不能进行减运算

 

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-9-ca5169d0bf6c> in <module>()----> 1C - D # 不同形状的矩阵不能进行减运算ValueError: operands could not be broadcast together with shapes (2,3) (3,2)

 

2.2.2.数乘、数除

这个也比较简单,就是和每个元素相乘,eg:2×A,A原本的每一个元素都扩大了两倍

数除其实就是乘以倒数(1/x)

In [10]:

print(A)

 

[[1 2 3]
[4 5 6]
[7 8 9]]

In [11]:

# 比如2×A,A原本的每一个元素都扩大了两倍2 * A

Out[11]:

array([[ 2,  4,  6],
      [ 8, 10, 12],
      [14, 16, 18]])

In [12]:

print(A)

 

[[1 2 3]
[4 5 6]
[7 8 9]]

In [13]:

# 友情提醒:Numpy里面的运算基本上都是针对每一个元素A / 2

Out[13]:

array([[0.5, 1. , 1.5],
      [2. , 2.5, 3. ],
      [3.5, 4. , 4.5]])

 

2.2.3.矩阵乘法

矩阵乘法还是要用LaTex演示一下的,不然有些朋友可能还是觉得比较抽象:(大家有什么好用的LaTex在线编辑器可以推荐的)

拿上面那个方程组来演示一下:

⎡⎣⎢1231−15⎤⎦⎥[x1x2]==>⎧⎩⎨x1+x22x1−x23x1+5x2[112−135][x1x2]==>{x1+x22x1−x23x1+5x2

稍微变化一下就更形象了:

⎡⎣⎢1231−15⎤⎦⎥[x1x2y1y2]==>⎧⎩⎨x1+x22x1−x23x1+5x2⎧⎩⎨y1+y22y1−x23y1+5y2==>⎡⎣⎢x1+x22x1−x23x1+5x2y1+y22y1−y23y1+5y2⎤⎦⎥[112−135][x1y1x2y2]==>{x1+x22x1−x23x1+5x2{y1+y22y1−x23y1+5y2==>[x1+x2y1+y22x1−x22y1−y23x1+5x23y1+5y2]

举个简单的例子:A×B

[1324][4231]=[1∗4+2∗23∗4+4∗21∗3+2∗13∗3+4∗1]=[820513][1234][4321]=[1∗4+2∗21∗3+2∗13∗4+4∗23∗3+4∗1]=[852013]

以后记不得怎么乘就自己推一下,值得注意的是:

两个矩阵的乘法仅当第一个矩阵A的列数(column)和另一个矩阵B的行数(row)相等才可以进行计算

你这样想就记得了:[1324][x1]还原成方程组就是这样{1∗x1+2∗?3∗x1+4∗?这是什么鬼?至少得这样吧:[1324][x1x2][1234][x1]还原成方程组就是这样{1∗x1+2∗?3∗x1+4∗?这是什么鬼?至少得这样吧:[1234][x1x2]

In [14]:

# 通过代码看一看A = np.array([[1,2],[3,4]])B = np.array([[4,3],[2,1]])print(A)print("-"*5)print(B)

 

[[1 2]
[3 4]]
-----
[[4 3]
[2 1]]

In [15]:

# 注意一下,Numpy里面的乘法默认是每个数对应相乘# 如果是矩阵相乘可以使用dot()方法# 或者你创建矩阵对象,这样×默认就是矩阵乘法了A.dot(B) # 矩阵A×矩阵B

Out[15]:

array([[ 8,  5],
      [20, 13]])

 

程序验证了我们上面的运算结果,还得注意一下:

A×B和B×A是不一样的,eg:B×A

[4231][1324]=[4∗1+3∗32∗1+1∗34∗2+3∗42∗2+1∗4]=[135208][4321][1234]=[4∗1+3∗34∗2+3∗42∗1+1∗32∗2+1∗4]=[132058]

如果你乘着乘着就忘记到底怎么乘,就把右边的矩阵换成x1,x2,然后就会了

In [16]:

print(A)print("-"*5)print(B)

 

[[1 2]
[3 4]]
-----
[[4 3]
[2 1]]

In [17]:

B.dot(A) # 矩阵B×矩阵A

Out[17]:

array([[13, 20],
      [ 5,  8]])

In [18]:

################ 变化来了 ################

In [19]:

# 来验证一下”两个矩阵的乘法仅当第一个矩阵A的列数(column)和另一个矩阵D的行数(row)相等才可以进行计算“print(A)print("-"*5)print(D)

 

[[1 2]
[3 4]]
-----
[[0 1]
[2 3]
[4 5]]

In [20]:

# A有2列 D有3行A.dot(D) # 不能乘

 

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-20-c1a9f22a6f8d> in <module>()      1 # A有2列 D有3行----> 2A.dot(D) # 不能乘ValueError: shapes (2,2) and (3,2) not aligned: 2 (dim 1) != 3 (dim 0)

In [21]:

# 你反过来就符合A的列数=D的行数了D.dot(A)

Out[21]:

array([[ 3,  4],
      [11, 16],
      [19, 28]])

 

2.2.4.幂乘、幂运算

幂乘比较简单,就是每个元素开平方,不一定是方阵

必须是方阵才能进行幂运算,比如A²=A×A(矩阵相乘前提:第一个矩阵A的行=第二个矩阵A的列==>方阵)

In [22]:

print(A)print("-"*5)print(C)

 

[[1 2]
[3 4]]
-----
[[0 1 2]
[3 4 5]]

In [23]:

# 幂乘(每个元素开平方) np.power(A,2) # 使用 A**2也一样

Out[23]:

array([[ 1,  4],
      [ 9, 16]])

In [24]:

# 幂乘(不一定是方阵) np.power(C,2)

Out[24]:

array([[ 0,  1,  4],
      [ 9, 16, 25]])

In [25]:

################ 方阵幂运算 ################

In [26]:

# A*A*Anp.linalg.matrix_power(A,3)

Out[26]:

array([[ 37,  54],
      [ 81, 118]])

In [27]:

# 不是方阵就overnp.linalg.matrix_power(C,3)

 

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-27-73f04ef7b54c> in <module>()      1 # 不是方阵就over----> 2np.linalg.matrix_power(C,3)~/anaconda3/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py in matrix_power(M, n)    137     M = asanyarray(M)    138     if M.ndim != 2 or M.shape[0] != M.shape[1]:--> 139raise ValueError("input must be a square array")    140     if not issubdtype(type(n), N.integer):    141         raise TypeError("exponent must be an integer")ValueError: input must be a square array

 

来个小结 + 扩展:

矩阵的加法运算满足交换律:A + B = B + A

矩阵的乘法满足结合律和对矩阵加法的分配律:

结合律:(AB)C = A(BC)

左分配律:(A + B)C = AC + BC

右分配律:C(A + B) = CA + CB

矩阵的乘法与数乘运算之间也满足类似结合律的规律;与转置之间则满足倒置的

分配律:c(A + B) = cA + cB

结合律:c(AB) = (cA)B = A(cB)

矩阵乘法不满足交换律 一般来说,矩阵A及B的乘积AB存在,但BA不一定存在,即使存在,大多数时候AB ≠ BA

2.3.特殊矩阵

2.3.1.零矩阵

零矩阵就是所有的元素都是0

⎡⎣⎢000000000⎤⎦⎥[000000000]

同样的:全1矩阵就是所有元素都是1

⎡⎣⎢111111111⎤⎦⎥[111111111]

In [1]:

import numpy as np

In [2]:

# 一维# 可以指定类型 np.zeros(5,dtype=int)np.zeros(5) # 完整写法:np.zeros((5,))

Out[2]:

array([0., 0., 0., 0., 0.])

In [3]:

# 二维np.zeros((2,5))# 建议用元组,官方文档都是元组

Out[3]:

array([[0., 0., 0., 0., 0.],
      [0., 0., 0., 0., 0.]])

In [4]:

# 三维 ==> 可以这么理解,2个2*5(2行5列)的矩阵np.zeros((2,2,5))

Out[4]:

array([[[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]],

      [[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]]])

In [5]:

################ 全1矩阵 ################

In [6]:

# `np.ones(tuple)` 用法和`np.zeros(tuple)`差不多# 可以指定类型 np.ones(5,dtype=int)# 一维np.ones(5) # 完整写法 np.ones((5,))

Out[6]:

array([1., 1., 1., 1., 1.])

In [7]:

# 二维,传一个shape元组np.ones((2,5))

Out[7]:

array([[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]])

In [8]:

# 三维 可以理解为两个二维数组np.ones((2,2,5))

Out[8]:

array([[[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]],

      [[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]]])

In [9]:

################ 指定值矩阵 ################

In [10]:

# 创建指定值的矩阵:np.full((3,5),222)

Out[10]:

array([[222, 222, 222, 222, 222],
      [222, 222, 222, 222, 222],
      [222, 222, 222, 222, 222]])

In [11]:

# 创建指定值的矩阵,浮点类型np.full((3,5),222.0)

Out[11]:

array([[222., 222., 222., 222., 222.],
      [222., 222., 222., 222., 222.],
      [222., 222., 222., 222., 222.]])

 

2.3.3.转置矩阵

转置矩阵 :将矩阵的行列互换得到的新矩阵(行列式不变)

m行×n列的矩阵行和列交换后就变成了n行×m列的矩阵,eg:3行×2列 ==> 2行×3列

⎡⎣⎢135246⎤⎦⎥T==>[123456][123456]T==>[135246]

矩阵的转置满足分配律:

(A+B)T=AT+BT(A+B)T=AT+BT

(AB)T=BTAT(AB)T=BTAT

再次提醒:两个矩阵的乘法仅当第一个矩阵A的列数(column)和另一个矩阵B的行数(row)相等才可以进行计算

In [12]:

A = np.arange(6).reshape((2,3))print(A)

 

[[0 1 2]
[3 4 5]]

In [13]:

# 转置矩阵(行列互换)A.T

Out[13]:

array([[0, 3],
      [1, 4],
      [2, 5]])

In [14]:

B = np.random.randint(10,size=(2,3))print(B)

 

[[4 4 7]
[5 3 9]]

In [15]:

################ 验证系列 ################

In [16]:

# 验证一下(A+B)^T=A^T+B^Tprint(A.T + B.T)print("-"*5)print((A+B).T)

 

[[ 4  8]
[ 5  7]
[ 9 14]]
-----
[[ 4  8]
[ 5  7]
[ 9 14]]

In [17]:

# 验证一下(A+B)^T=A^T+B^T# 其实也再一次验证了,Numpy运算符默认是对每一个元素的操作(A+B).T == A.T + B.T

Out[17]:

array([[ True,  True],
      [ True,  True],
      [ True,  True]])

In [18]:

################ 验证系列 ################

In [19]:

# 把A变成3*2的矩阵,不够元素用0补# reshape:有返回值,不对原始多维数组进行修改# resize:无返回值,会对原始多维数组进行修改A.resize(3,2)print(A)print(B)

 

[[0 1]
[2 3]
[4 5]]
[[4 4 7]
[5 3 9]]

In [20]:

# 验证(AB)^T=B^T×A^Tprint((A.dot(B)).T)print("-"*5)print((B.T).dot(A.T))

 

[[ 5 23 41]
[ 3 17 31]
[ 9 41 73]]
-----
[[ 5 23 41]
[ 3 17 31]
[ 9 41 73]]

 

2.3.3.上三角矩阵和下三角矩阵

上三角矩阵 :主对角线以下都是零的方阵

⎡⎣⎢⎢⎢2000970043607311⎤⎦⎥⎥⎥[2947073300610001]

下三角矩阵 :主对角线以上都是零的方阵

⎡⎣⎢⎢⎢2351076200730004⎤⎦⎥⎥⎥[2000370056701234]

性质(行列式后面会说)

上(下)三角矩阵的行列式为对角线元素相乘

上(下)三角矩阵乘以系数后也是上(下)三角矩阵

上(下)三角矩阵间的加减法和乘法运算的结果仍是上(下)三角矩阵

上(下)三角矩阵的逆矩阵也仍然是上(下)三角矩阵

In [21]:

# 创建一个5行4列矩阵A = np.random.randint(10,size=(4,4))print(A)

 

[[3 5 2 3]
[7 2 9 6]
[5 1 7 6]
[1 2 8 4]]

In [22]:

# 上三角np.triu(A)

Out[22]:

array([[3, 5, 2, 3],
      [0, 2, 9, 6],
      [0, 0, 7, 6],
      [0, 0, 0, 4]])

In [23]:

# 下三角np.tril(A)

Out[23]:

array([[3, 0, 0, 0],
      [7, 2, 0, 0],
      [5, 1, 7, 0],
      [1, 2, 8, 4]])

In [24]:

# 验证一下最后一个性质# 三角矩阵的逆矩阵也仍然是三角矩阵print(np.triu(A).T)print('-'*5)print(np.tril(A).T)

 

[[3 0 0 0]
[5 2 0 0]
[2 9 7 0]
[3 6 6 4]]
-----
[[3 7 5 1]
[0 2 1 2]
[0 0 7 8]
[0 0 0 4]]

 

2.3.4.对角矩阵

对角矩阵 :主对角线之外的元素皆为0的方阵 (单位矩阵属于对角矩阵中的一种)

⎡⎣⎢000000000⎤⎦⎥⎡⎣⎢100010001⎤⎦⎥⎡⎣⎢200020002⎤⎦⎥⎡⎣⎢300090006⎤⎦⎥[000000000][100010001][200020002][300090006]

扩充:对角矩阵的运算包括和、差运算、数乘运算、同阶对角阵的乘积运算,且结果仍为对角阵

而且有意思的是:对角矩阵的矩阵幂运算等于其对应元素的幂运算

⎡⎣⎢300090006⎤⎦⎥n=⎡⎣⎢3n0009n0006n⎤⎦⎥[300090006]n=[3n0009n0006n]

In [25]:

# 简单创建np.diag([3,9,6])

Out[25]:

array([[3, 0, 0],
      [0, 9, 0],
      [0, 0, 6]])

In [26]:

np.diag([2,2,2])

Out[26]:

array([[2, 0, 0],
      [0, 2, 0],
      [0, 0, 2]])

In [27]:

################ 验证系列 ################

In [28]:

# np.diag?print(A)# 获取对角元素,然后再生成对角矩阵B = np.diag(A.diagonal()) #或者 np.diag(np.diag(A))print(B)

 

[[3 5 2 3]
[7 2 9 6]
[5 1 7 6]
[1 2 8 4]]
[[3 0 0 0]
[0 2 0 0]
[0 0 7 0]
[0 0 0 4]]

In [29]:

B.dot(B).dot(B)

Out[29]:

array([[ 27,   0,   0,   0],
      [  0,   8,   0,   0],
      [  0,   0, 343,   0],
      [  0,   0,   0,  64]])

In [30]:

# 对角矩阵的矩阵幂运算等于其对应元素的幂运算B**3

Out[30]:

array([[ 27,   0,   0,   0],
      [  0,   8,   0,   0],
      [  0,   0, 343,   0],
      [  0,   0,   0,  64]])

 

2.3.5.单位矩阵

单位矩阵 :单位矩阵是个方阵(行列相等),从左上角到右下角的对角线(称为主对角线)上的元素均为1。其他全都为0,eg:

⎡⎣⎢100010001⎤⎦⎥[100010001]

任何矩阵 x 单位矩阵 都等于其本身 (反过来也一样(这个和1×a=a×1一个道理))

In [31]:

# 定义一个2行的单位矩阵(列默认和行一致)# np.eye(rows,columns=rows)np.eye(2)

Out[31]:

array([[1., 0.],
      [0., 1.]])

In [32]:

################ 验证扩展 ################

In [33]:

# 可以指定类型B = np.eye(4,dtype=int)print(B)

 

[[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]]

In [34]:

print(A)

 

[[3 5 2 3]
[7 2 9 6]
[5 1 7 6]
[1 2 8 4]]

In [35]:

# 任何矩阵 x 单位矩阵 都等于其本身A.dot(B)

Out[35]:

array([[3, 5, 2, 3],
      [7, 2, 9, 6],
      [5, 1, 7, 6],
      [1, 2, 8, 4]])

In [36]:

# 反过来也一样(这个和1*a=a*1一个道理)B.dot(A)

Out[36]:

array([[3, 5, 2, 3],
      [7, 2, 9, 6],
      [5, 1, 7, 6],
      [1, 2, 8, 4]])

 

2.3.6.对称矩阵

对称矩阵 :元素以主对角线为对称轴对应相等的方阵

对称矩阵的转置是它本身:AT=AAT=A

In [37]:

A = np.random.randint(10,size=(4,4))print(A)

 

[[0 1 6 9]
[1 2 4 7]
[4 8 7 9]
[3 6 8 0]]

In [38]:

B = np.triu(A)B += B.T - np.diag(A.diagonal())print(B)

 

[[0 1 6 9]
[1 2 4 7]
[6 4 7 9]
[9 7 9 0]]

In [39]:

# 验证一下B.T == B

Out[39]:

array([[ True,  True,  True,  True],
      [ True,  True,  True,  True],
      [ True,  True,  True,  True],
      [ True,  True,  True,  True]])

In [40]:

################ 分步解释 ################

In [41]:

# 创建上三角矩阵B = np.triu(A)print(B)

 

[[0 1 6 9]
[0 2 4 7]
[0 0 7 9]
[0 0 0 0]]

In [42]:

# 上三角+它的逆矩阵(发现距离对角矩阵只是多加一次对角线上的元素)B += B.Tprint(B)

 

[[ 0  1  6  9]
[ 1  4  4  7]
[ 6  4 14  9]
[ 9  7  9  0]]

In [43]:

# 所以减去对角线上的元素,得到对角矩阵B - np.diag(A.diagonal())

Out[43]:

array([[0, 1, 6, 9],
      [1, 2, 4, 7],
      [6, 4, 7, 9],
      [9, 7, 9, 0]])

 

2.4.逆矩阵

逆矩阵 :设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得:AB=BA=E 则我们称B是A的逆矩阵(表示为A−1A−1),而A则被称为可逆矩阵

通俗话讲就是:原矩阵×逆矩阵=逆矩阵×原矩阵=单位矩阵

2.4.1.消元法

可能一看到逆矩阵,大家就想到代数余子式 ,不过逆天要说的是,代数余子式就和我们程序员面试题一样,有些题目就是又繁琐实际运用又没多大意义的题目一样,很多时候面试官都不看面试题一眼,同样的那些出题老师自己解题一般都不会使用。我这边介绍一下方便简单的方法“消元法”

比如求[3122]−1[3212]−1,就可以表示为:

[3122][x11x21x12x22]=[1001][3212][x11x12x21x22]=[1001]

转换成方程组:

⎧⎩⎨⎪⎪⎪⎪⎪⎪[3122][x11x21]=[10][3122][x12x22]=[01]==>求方程组{3x11+2x21=11x11+2x21=0和{3x12+2x22=01x12+2x22=1的解{[3212][x11x21]=[10][3212][x12x22]=[01]==>求方程组{3x11+2x21=11x11+2x21=0和{3x12+2x22=01x12+2x22=1的解

这样很轻松就能解出逆矩阵了

{x11=12x21=−14{x12=−12x22=34==>[12−14−1234]{x11=12x21=−14{x12=−12x22=34==>[12−12−1434]

In [44]:

A = np.array([[3,2],[1,2]])print(A)

 

[[3 2]
[1 2]]

In [45]:

# 求A的逆矩阵np.linalg.inv(A)

Out[45]:

array([[ 0.5 , -0.5 ],
      [-0.25,  0.75]])

 

2.4.2.二阶方阵公式

如果只是2阶方阵,有更简单的公式(只能2阶使用,而消元法不受限制)矩阵是否可逆就看分母是否为0

[a11a21a12a22]=1a11a22−a12a21[a22−a21−a12a11][a11a12a21a22]=1a11a22−a12a21[a22−a12−a21a11]

比如求[3122]−1[3212]−1:

13×2−2×1[2−1−23]=[12−14−1234]13×2−2×1[2−2−13]=[12−12−1434]

扩展系列:伪逆矩阵

非方阵可以求 伪逆矩阵 AXA=A,XAX=X

判断矩阵是否可逆:


det[a11a21a12a22]=a11a12−a12a21det⎡⎣⎢a11a21a31a12a22a32a13a23a33⎤⎦⎥=a11a22a33+a12a23a31+a13a21a32−a13a22a31−a12a21a33−a11a23a32det[a11a12a21a22]=a11a12−a12a21det[a11a12a13a21a22a23a31a32a33]=a11a22a33+a12a23a31+a13a21a32−a13a22a31−a12a21a33−a11a23a32


方法很多(比如还可以通过余子式),公式其实有规律,你可以先摸索下(给个提示):

正负

a11a22    +    

a12a21    -    

正负

a11a22a33    +    

a11a23a32    -    

a12a21a33    -    

a12a23a31    +    

a13a21a32    +    

a13a22a31    -    

程序比较简单:np.linalg.det(A)

In [46]:

A = np.array([[7, 3, 6],[5, 3, 1]])print(A)

 

[[7 3 6]
[5 3 1]]

In [47]:

# 不等于0就是可逆np.linalg.det(A)

 

---------------------------------------------------------------------------LinAlgError                               Traceback (most recent call last)<ipython-input-47-2ce8e7bdf499> in <module>()      1 # 不等于0就是可逆----> 2np.linalg.det(A)~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in det(a)   1869     a = asarray(a)   1870     _assertRankAtLeast2(a)-> 1871_assertNdSquareness(a)   1872     t, result_t = _commonType(a)   1873     signature = 'D->D' if isComplexType(t) else 'd->d'~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays)    209     for a in arrays:    210         if max(a.shape[-2:]) != min(a.shape[-2:]):--> 211raise LinAlgError('Last 2 dimensions of the array must be square')    212     213 def _assertFinite(*arrays):LinAlgError: Last 2 dimensions of the array must be square

In [48]:

# 必须是方阵的验证np.linalg.inv(A)

 

---------------------------------------------------------------------------LinAlgError                               Traceback (most recent call last)<ipython-input-48-0af3c81a492f> in <module>()      1 # 必须是方阵的验证----> 2np.linalg.inv(A)~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in inv(a)    521     a, wrap = _makearray(a)    522     _assertRankAtLeast2(a)--> 523_assertNdSquareness(a)    524     t, result_t = _commonType(a)    525 ~/anaconda3/lib/python3.6/site-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays)    209     for a in arrays:    210         if max(a.shape[-2:]) != min(a.shape[-2:]):--> 211raise LinAlgError('Last 2 dimensions of the array must be square')    212     213 def _assertFinite(*arrays):LinAlgError: Last 2 dimensions of the array must be square

In [49]:

# 有时候还是需要求逆矩阵# 那就可以求它的伪逆矩阵X = np.linalg.pinv(A)print(X)

 

[[-0.00632911  0.15189873]
[-0.05696203  0.16708861]
[ 0.20253165 -0.26075949]]

In [50]:

# A*X*A=AA.dot(X).dot(A)

Out[50]:

array([[7., 3., 6.],
      [5., 3., 1.]])

In [51]:

# X*A*X=XX.dot(A).dot(X)

Out[51]:

array([[-0.00632911,  0.15189873],
      [-0.05696203,  0.16708861],
      [ 0.20253165, -0.26075949]])

In [52]:

################ 简单说下mat ################

In [53]:

# 创建一个矩阵A = np.mat([[3,2],[1,2]])print(A)type(A)

 

[[3 2]
[1 2]]

Out[53]:

numpy.matrixlib.defmatrix.matrix

In [54]:

# 求它的逆矩阵A.I

Out[54]:

matrix([[ 0.5 , -0.5 ],
       [-0.25,  0.75]])

In [55]:

# A^TA.T

Out[55]:

matrix([[3, 1],
       [2, 2]])

In [56]:

# *默认就是矩阵乘法A * A

Out[56]:

matrix([[11, 10],
       [ 5,  6]])

In [57]:

# 更多自己查看下帮助文档把,用法和array基本上一样,# 我这边只是简单提一下,怕你们不去看(所有和矩阵相关的东西,里面都有封装,很方便)np.mat?



本文由职坐标整理并发布,希望对同学们学习Python有所帮助,更多内容请关注职坐标编程语言Python频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程