1、 关于矩阵
填数游戏我们以前都玩过,它是一个九宫格。要求在九宫格的空格里填数,使横行、竖行、斜行上的三个数的和等于18。

为了叙说方便,在原有九宫格的基础上加上序号,横向为行,纵向为列。横向从上到下依次为1、2、3行,纵向从左到右依次为1、2、3列。

用大写黑体字母A表示九宫格,用行号和列号来表示九宫格内每个格子的数。例如:A[2,1]的数为10,也就是第2行第1列的数为10;A[1,3]的数为7,也就是第1行第3列的数为7;A[2,2]的数为6,也就是第2行第2列的数为6。
简便起见,也可以以下标方式表示每个格子的数。例如:A2,1等同于A[2,1];A1,3等同于A[1,3];A2,2等同于A[2,2]。
准备工作做好后,现在可以开始解题了。我们注意到A的第二行A[2,1]和A[2,2]的数分别为8和6,A[2,3]只能填数2。 A[2,3]的数确定后,A[3,3]的数也会确定下来,A[3,3]的数是9。

同样的解题思路,可以依次算出A[1,1]、A[3,1]、A[1,2]、A[3,2]的数。

现在把九宫格的表格线去掉,行号和列号也去掉,让它变换成下面的样子。
去除表格线的九宫格,就是矩阵的样式。矩阵是由行和列组成的一组数表,矩阵使用大写黑体字母表示,矩阵中的元素使用行下标和列下标来表示。矩阵一般用下面的形式表示。

其中,大写黑体字母A是矩阵的标识名称,标识名称下面的3 X 3表示3行3列矩阵。矩阵A共有3 X 3=9个数,这9个数称为矩阵的元素,A[1,1]表示第1行第1列的元素,A[1,2]表示第1行第2列的元素,……,依次类推,A[3,3]表示第3行第3列的元素。矩阵A也可以表示为A33。
要在Numpy内构造矩阵,使用array()函数创建二维数组即可。
例1 使用Numpy数组构造矩阵A
>>> import numpy as np >>> a = np.array([[3,8,7], [10,6,2], [5,4,9]])
例2 矩阵的加法和减法运算
案例代码见课程资源(unit2\case09.py)
#定义矩阵A和B A = [[-1,3,2],[5,7,-2],[-3,0,1]] B = [[8,2,-1],[6,4,0],[-2,3,5]] #定义矩阵C,存储A+B的结果 C = [[0,0,0],[0,0,0],[0,0,0]] #定义矩阵D,存储A-B的结果 D = [[0,0,0],[0,0,0],[0,0,0]] # 遍历A矩阵的行 for i in range(len(A)): # 遍历A矩阵的列 for j in range(len(A[0])): C[i][j] = A[i][j] + B[i][j] D[i][j] = A[i][j] - B[i][j] #输出C矩阵 for r in C: print(r) #输出D矩阵 for r in D: print(r)
例3 实现A矩阵与B矩阵的乘法运算。

案例代码见课程资源(unit2\case10.py)
import numpy as np #定义矩阵A和B A = np.array([[15,28,5],[12,31,6],[13,29,7]]) B = np.array([[4],[3],[2]]) #定义矩阵乘法运算函数 def matrixMul(A, B): #NumPy的matmul完成矩阵乘法运算 C = np.matmul(A,B) return C if __name__ == '__main__': C = matrixMul(A,B) print(C) Numpy库的matmul()函数可以实现矩阵乘法运算。 例4 实现矩阵的转置运算 矩阵的转置比较容易理解,就是把矩阵的行列互换,行变成列,列变成行。 案例代码见课程资源(unit2\case11.py) import numpy as np #定义矩阵A A = np.array([[1,1],[3,7],[11,5]]) #定义矩阵转置运算函数 def matrixTranspos(A): #创建矩阵C,矩阵C的默认元素都为0 #矩阵C的行数为A矩阵的列数,列数为A矩阵的行数 C = [[0] * len(A) for i in range(len(A[0]))] #NumPy的transpose完成矩阵A的转置运算 C = np.transpose(A) return C if __name__ == '__main__': C = matrixTranspos(A) print(C)
Numpy库的transpose()函数可以实现矩阵转置运算。
2、 向量
n X 1的矩阵称为列向量,1 X m的矩阵也称为行向量。行向量经过转置运算可以变换为列向量。下图是一个列向量:

向量在线性代数中使用小写的黑体字母表示,如α、β、γ … 或a、b、c … 等来表示,也可以在字母上面加一箭头表示。向量在几何中用有向线段来表示,有向线段的长度表示向量的大小,箭头所指的方向表示向量的方向。
向量是定义在实数(暂不考虑复数域)集合上的一组有序的特定值,有序是指这一组数中位置顺序不能颠倒,也不能互换,如果顺序颠倒或互换就是另外一个向量了。

上图中a向量和b向量是两个不同的向量。它是一个二维向量,每个向量有两个元素,每个元素称为向量的一个分量。a向量和b向量的元素数值就是单纯的实数,可以为向量元素赋予不同的意义。
例如:在二维坐标系中,向量a和b的元素就是二维坐标系中的坐标点,向量的第一个分量是x坐标,第二个分量是y坐标,a向量和b向量的几何表示如下图所示:

在三维坐标系中向量就需要三个分量来表示,下图是在三维空间中的向量a和b:

上图a和b向量的元素是三维空间中的坐标点。a向量的第一个分量是2,是三维空间的x坐标;a向量的第二个分量是1,是三维空间的y坐标;a向量的第三个分量是3,是三维空间的z坐标。同理,b向量的第一个分量是3,是三维空间的x坐标;b向量的第二个分量是0,是三维空间的y坐标;b向量的第三个分量是1,是三维空间的z坐标。
用向量也可以表示事物的一组特征。例如人的健康基本特征有体重、身高、血压(高压/低压)、脉搏,可以构建一个五维向量,来描述体重、身高、血压(高压/低压)、脉搏五个健康特征,人的体重、身高、血压(高压/低压)、脉搏的数值就是这个五维向量的五个分量。
构建的五维向量可以作为健康识别函数的输入,健康识别函数的输出为人的健康指标。下图是一个具有五个维度的健康特征向量:

在NumPy中,创建向量和创建矩阵是一样的,也是使用 NumPy的array函数来创建向量。
例5 向量的创建
案例代码见课程资源(unit2\case12.py)
#创建二维行向量row_a
row_a = np.array([[2,1]])
#创建五维列向量col_health
col_health = np.array([[1.73],[65],[120],[82],[75]])
#创建五维行向量row_health
row_health = np.array([[1.73,65,120,82,75]])
if __name__ == '__main__':
#输出列向量col_a
print("col_a=")
print(col_a)
#输出列向量col_a的维数
print("col_a的维数:")
print(col_a.shape)
#输出行向量row_a
print("row_a")
print(row_a)
#输出行向量row_a的维数
print("row_a的维数:")
print(row_a.shape)
#输出行向量row_a的转置
print("输出row_a的转置:")
print(np.transpose(row_a))
#输出列向量col_health
print("col_health=")
print(col_health)
#输出列向量col_health的维数
print("col_health的维数:")
print(col_health.shape)3、 解线性方程组
假如猪肉、牛肉、鸡蛋的价格在一周内不发生变化,记录近三周内的价格。为计算简单起见,价格都设定为整数。
设某个家庭每周对猪肉、牛肉、鸡蛋的需求分别为4千克、3千克、2千克,求这个家庭近三周对上述三种食品的需求开支?
一般计算过程为:
第一周:15 X 4 + 28 X 3 + 5 X 2 = 154
第二周:12 X 4 + 31 X 3 + 6 X 2 = 153
第三周:13 X 4 + 29 X 3 + 7 X 2 = 153
现在把上面的数据用矩阵来表示,矩阵A表示猪肉、牛肉、鸡蛋三周的价格,矩阵B表示某个家庭每周的需求。

下面用线性方程组求解。
设某家庭近三周每周对猪肉、牛肉、鸡蛋的需求分别为x千克、y千克、z千克,已知近三周每周猪肉、牛肉、鸡蛋的价格和某家庭近三周每周的消费,求x、y和z。
可以列三元一次方程组:
15x + 28y + 5z = 154
12x + 31y + 6z = 153
13x + 29y + 7z = 153
可以把上面方程组的系数、未知数、常数用矩阵的方式来表示,这样就可以使用矩阵运算来求解方程组。

求解三元一次方程组的问题就变为:
已知A矩阵,已知A矩阵和B矩阵的乘积C矩阵,求B矩阵的问题。Numpy库的 linalg模块的solve()函数可以使用矩阵求解线性方程组。
例6 求解线性方程组
案例代码见课程资源(unit2\case13.py)
# 导入numpy库
import numpy as np
# 程序入口
if __name__ == '__main__':
# 建立3X3矩阵
ta = np.array([[15,28,5],
[12,31,6],
[13,29,67]
])
# 建立3维行向量
tb = np.array([154,153,153])
# 解线性方程组
x = np.linalg.solve(ta,tb)
# 输出x、y、z的值
print("x = %.2f y = %.2f z = %.2f" % (x[0],x[1],x[2]))