十、矩阵
在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合
如:
[111213212223313233]
\left[ \begin{array}{ccc}
11 & 12 & 13\\
21 & 22 & 23\\
31 & 32 & 33\\
\end{array}
\right ]
⎣⎡112131122232132333⎦⎤
矩阵是高等代数学中的常见工具
在numpy 中提供了用来表示矩阵的numpy.matrix类型,该类继承自numpy.ndarray,任何针对多维数组的操作,对矩阵同样有效,但是作为子类矩阵又结合其自身的特点,做了必要的扩充,比如:乘法计算、矩阵求逆等。
创建matrix对象的方法:
numpy.matrix()函数
1. 矩阵对象的创建
# 通过ndarray对象创建matrix对象
numpy.matrix(
data, # 二维容器或' '或',' 分隔列,';'分隔行的字符串
dtype=None, # 数据类型
copy=True # 是否复制数据(缺省值为True,即复制数据)
)
创建matrix示例:
# 创建matrix操作
import numpy as np
arr = np.arange(1, 10).reshape(3, 3)
print(arr)
# 第一种方式
m = np.matrix(arr, copy=True)
print(m)
print(m.shape)
print(type(m))
# 第二种方式
m2 = np.matrix("1 2 3;4 5 6")
print(m2)
# 第三种方式
m3 = np.matrix("1, 2, 3;4, 5, 6;7, 8, 9")
print(m3)
2. 矩阵的乘法运算(点乘)
矩阵点乘运算
矩阵点乘只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义
如:
KaTeX parse error: Undefined control sequence: \
at position 26: …[\begin{array} \̲
̲a_{11}&a_{12}&a…
KaTeX parse error: Undefined control sequence: \ at position 26: …[\begin{array} \̲ ̲b_{11}&b_{12} \…
KaTeX parse error: Undefined control sequence: \ at position 38: …[\begin{array} \̲ ̲a_{11}b_{11}+a_…
示例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f7twMQG3-1639224038382)(./img/%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95.png)]
矩阵乘法规则:
- 当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘
- 矩阵C的行数等于矩阵A的行数,C的列数等于B的列数
- 乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和
numpy.ndarray、numpy.matrix和pandas.DataFrame 都提供了多种方式的矩阵点乘,如:
a @ b
a.dot(b)
示例:
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[10, 20],
[30, 40],
[50, 60]])
c = a @ b
print(c)
# [[220 280]
# [490 640]]
示例:
某公司有四个工厂,分布在不同地区,同时三种产品,产量(单位;t):
产品 工厂 ```````` | P1 | P2 | P3 |
---|---|---|---|
甲 | 5 | 2 | 4 |
乙 | 3 | 8 | 2 |
丙 | 6 | 0 | 4 |
丁 | 0 | 1 | 6 |
对应矩阵如下:
[524382604016]
\left[ \begin{array}{ccc}
5 & 2 & 4\\
3 & 8 & 2\\
6 & 0 & 4\\
0 & 1 & 6\\
\end{array}
\right ]
⎣⎢⎢⎡536028014246⎦⎥⎥⎤
第一列表示三种产品的单件利润,第二列表示三种产品的单件体积
单件利润 | 单件体积 | |
---|---|---|
P1 | 2 | 4 |
P2 | 1 | 3 |
P3 | 3 | 2 |
对应矩阵如下:
[241332]
\left[ \begin{array}{ccc}
2 & 4\\
1 & 3\\
3 & 2\\
\end{array}
\right ]
⎣⎡213432⎦⎤
计算各个生产厂的商品总利润和产品的总体积
[524382604016]∙[241332]=[2434204024321915]
\left[ \begin{array}{ccc}
5 & 2 & 4\\
3 & 8 & 2\\
6 & 0 & 4\\
0 & 1 & 6\\
\end{array}
\right ]
\bullet
\left[ \begin{array}{ccc}
2 & 4\\
1 & 3\\
3 & 2\\
\end{array}
\right ] =
\left[ \begin{array}{ccc}
24 & 34\\
20 & 40\\
24 & 32\\
19 & 15\\
\end{array}
\right ]
⎣⎢⎢⎡536028014246⎦⎥⎥⎤∙⎣⎡213432⎦⎤=⎣⎢⎢⎡2420241934403215⎦⎥⎥⎤
示例:
# 矩阵乘法
import numpy as np
import pandas as pd
a = np.array([
[5, 2, 4],
[3, 8, 2],
[6, 0, 4],
[0, 1, 6],
])
b = np.array([
[2, 4],
[1, 3],
[3, 2],
])
# 数组相乘, 各对应位置元素相乘
result = a @ b # 矩阵相乘,第n行乘m列之和,作为结果的n,m个元素
print(result)
ma = np.matrix(a)
mb = np.matrix(b)
mr = ma @ mb # 或 mr = ma*mb 矩阵matrix 的 *乘法等同于 @乘法
print(mr)
df_a = pd.DataFrame(a, index=['甲', '乙', '丙', '丁'])
df_b = pd.DataFrame(b, columns=['总利润', '总体积'])
print(df_a @ df_b)
print(df_a.dot(df_b))
3. 单位矩阵
在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,这种矩阵被称为单位矩阵。它是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1,除此以外全都为0,记为InI_nIn或EnE_nEn ,通常用I或E来表示。
根据单位矩阵的特点,任何矩阵与单位矩阵相乘都等于本身,而且单位矩阵因此独特性有广泛用途。以下是一个单位矩阵示例:
E3=[100010001]
E_3 =
\left[ \begin{array}{ccc}
1 & 0 & 0\\
0 & 1 & 0\\
0 & 0 & 1\\
\end{array}
\right ]
E3=⎣⎡100010001⎦⎤
在numpy 中。可以用 numpy.identity(n) 或 numpy.eye(n) 来生成一个单位矩阵
以下是一个单位矩阵的示例:
# 单位矩阵示例
import numpy as np
e = np.matrix("1 2 3; 4 5 6; 7 8 9")
unit = np.identity(3, dtype=int) #产生单位矩阵
print(e)
print(unit)
print("===============================")
print(e * unit)
4. 矩阵的逆矩阵
若两个矩阵A、B满足:AB = BA = E (E为单位矩阵),则成为A、B为逆矩阵(结合四则运算中的倒数理解)。
numpy 中用matrix.I 求取逆矩阵或者 使用numpy.linalg.inv(…) 函数求取逆矩阵
示例
import numpy as np
a = np.matrix("1 2 6; 3 5 7; 4 8 9")
print('------a------')
print(a)
print('------a 的逆矩阵a.I ------')
print(a.I)
print('------a 的逆矩阵np.linalg.inv(a) ------')
print(np.linalg.inv(a))
print('------a * a.I 的逆矩阵 ------')
print(a * a.I)
# 非方阵的逆(称为广义逆矩阵)
b = np.matrix("1 2 6; 3 5 7")
print(b)
print(b.I)
print(b * b.I)
注意:在计算过程中,可能出现如下错误,说明该矩阵不可逆。
numpy.linalg.LinAlgError: Singular matrix
5. 矩阵应用
案例1:假设一帮孩子和家长出去旅游,去程坐的是bus,小孩票价为3元,家长票价为3.2元,共花了118.4;回程坐的是Train,小孩票价为3.5元,家长票价为3.6元,共花了135.2。分别求小孩和家长的人数。使用矩阵求解。
假设 小孩人数 xxx 人,大人人数yyy 人
列方程:
3x+3.2y=118.43.5x+3.6y=135.2
3x + 3.2y = 118.4\\
3.5x + 3.6y = 135.2
3x+3.2y=118.43.5x+3.6y=135.2
表示成矩阵相乘:
$$
\left[ \begin{array}{ccc}
3 & 3.2 \
3.5 & 3.6 \
\end{array} \right]
\times
\left[ \begin{array}{ccc}
x \
y \
\end{array} \right]
\left[ \begin{array}{ccc}
118.4 \
135.2 \
\end{array} \right]
$$
numpy 提供了两种方法求方程的解:
-
numpy.linalg.lstsq(A, B)[0] 求最小二乘解
-
numpy.linalg.solve(A, B) 求解线性方程的解
import numpy as np
# 解方程
prices = np.matrix('3 3.2; 3.5 3.6')
totals = np.matrix('118.4; 135.2')
x = np.linalg.lstsq(prices, totals)[0] # 求最小二乘解
print(x)
x = np.linalg.solve(prices, totals) # 求解线性方程的解
print(x)
x = prices.I * totals # 利用矩阵的逆进行求解
print(x)
把逆矩阵的概念推广到非方阵,即称为广义逆矩阵。
案例2:斐波那契数列
1 1 2 3 5 8 13 21 34 …
X 1 1 1 1 1 1
1 0 1 0 1 0
--------------------------------
1 1 2 1 3 2 5 3
1 0 1 1 2 1 3 2
F^1 F^2 F^3 F^4 ... f^n
代码
import numpy as np
n = 35
# 使用递归实现斐波那契数列
def fibo(n):
return 1 if n < 3 else fibo(n - 1) + fibo(n - 2)
print(fibo(n))
# 使用矩阵实现斐波那契数列
print(int((np.matrix('1. 1.; 1. 0.') ** (n - 1))[0, 0]))