编程学习网 > 编程语言 > Python > python矩阵教程(Python矩阵的创建和运算)
2023
07-10

python矩阵教程(Python矩阵的创建和运算)

Python是可以很方便地计算代数运算的,主要的支持库就是Numpy,它是Python最优秀的、基础的、实现数值计算的第三方库。

Numpy库就是基于数组来运算的,正是因为这个,使得Python做数值计算的速度非常快。所谓数组,在代数运算中就可以理解为矩阵。一般而言,我们的矩阵是一个二维的,由行列指标组成的。Numpy的数组不仅仅支持二维的数组,还可以创建更高维度的数组,比如三维的图像数据就是使用三维数组来存储的。下面提到的矩阵,不加一般说明,就是指二维数组。
创建矩阵
学会使用Python做矩阵计算的前提是创建矩阵,下面就给出几种不同创建矩阵的方式。
创建向量,再重构行列数,得到二维的数组。
使用二维列表创建矩阵。
通过特殊函数创建特殊矩阵。
上面所提到的向量,不会区分行向量还是列向量,可以理解为一行元素或者一列元素。原因有二:其一,向量不参与代数运算时,作出区分是无意义的。其二,代数运算中,向量可以直接与矩阵作运算的,但是在Python程序中是不可以的,必须是矩阵与矩阵之间作运算,也就是说,要将向量“显示地”转化为1行n列或者n行一列的矩阵。如何“显示地”转换,就是对它进行行列数重构。
我们所说的第一种创建矩阵的方式,是先要创建向量,那么如何创建向量呢?也有两种方式:
使用列表或者元组创建向量。
使用特殊函数来创建向量。
先看第一种简单的方式,使用列表或者元素来创建向量,执行下面的代码:
import numpy as np # 导入必要的包,这是必要的,后面书写上可能会省略
lst = [1,2,3,4,5,0,9,8,7,6]
vec = np.array(lst) # 使用np.array()函数来创建向量,同时也可以创建矩阵
print(vec)
程序输出的结果如下:
[1 2 3 4 5 0 9 8 7 6]
下面使用几个特殊的函数来创建几个特殊的向量,执行下面的代码:
vec1 = np.arange(10) # 默认从0开始,步长为1,截止到9
vec2 = np.ones(10) # 创建10个1的向量
vec3 = np.zeros(5) # 创建5个0的向量
start = 1
end = 11
vec4 = np.arange(start, end) # 创建10个元素的向量,1,2,...,10
vec5= np.empty(5) # 创建5个元素的空向量
length = 10
value = 3
vec6 = np.full(shape=length,fill_value=value)
print(vec1, vec2, vec3, vec4, vec5, vec6, sep="\n")
程序输出的结果如下:
[0 1 2 3 4 5 6 7 8 9]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[0. 0. 0. 0. 0.]
[ 1  2  3  4  5  6  7  8  9 10]
[1.32774279e-311 8.01304531e+262 2.60799828e-310 1.32624737e-311 0.00000000e+000]
[3 3 3 3 3 3 3 3 3 3]
需要注意的是,empty函数得到的“空向量”是一个非常小的数组成的向量,而这些非常小的数是随机生成的。
现在来创建矩阵,先看第一种方法。创建向量再重构行列,重构是使用方法reshape。
row = 4
col = 5 # 行、列只需要指定一个即可,另一个写成-1
mat1 = np.arange(20).reshape(row, -1)
mat2 = np.reshape(np.arange(1,21), (row, col))
print(mat1, mat2, sep='\n')
程序输出的结果如下:
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]]
第二种方式,使用二维列表创建矩阵,执行下面的代码:
lst = [[1,2,3], [3,2,1], [4,5,6]]
mat = np.array(lst)
print(mat)
程序输出的结果如下:
[[1 2 3]
 [3 2 1]
 [4 5 6]]
第三种生成矩阵的方式,是使用特殊函数直接生成矩阵。
row = 3
col = 5
mat1 = np.ones((row, col)) # 1矩阵,直接生成必须填写一个元组作为参数
mat2 = np.zeros((row, col)) # 0矩阵,元组作参数
mat3 = np.full(shape=(row, col), fill_value=5) # 全值矩阵
print(mat1, mat2, mat3, sep='\n')
程序输出的结果如下:
[[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]]
[[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
[[5 5 5 5 5]
 [5 5 5 5 5]
 [5 5 5 5 5]]
下面使用一个最实用的函数来创建单位矩阵:
mat = np.identity(4) # 创建一个4×4的单位阵
print(mat)
程序输出的结果如下:
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
矩阵的简单计算
这里所谓的矩阵简单计算,主要是矩阵的加法和乘法。加法直接使用符号"+"即可,矩阵的数乘使用符号"*"即可,但是矩阵的乘法必须使用点乘形式,"A.dot(B)",或者是"np.dot(A,B)",其中的A和B是矩阵。
执行下面的代码:
mat1 = np.array([[1,2,3], [4,5,6],[7,8,9]])
mat2 = np.arange(15).reshape(3,-1)
mat3 = np.identity(3)
mat4 = mat1+mat3 # 矩阵的加法
mat5 = mat1.dot(mat3) # 矩阵的乘法
mat6 = mat1 * mat3 # 矩阵对应元素相乘
print(mat4, mat5, mat6, sep='\n')
程序输出的结果如下:
[[ 2.  2.  3.]
 [ 4.  6.  6.]
 [ 7.  8. 10.]]
[[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
[[1. 0. 0.]
 [0. 5. 0.]
 [0. 0. 9.]]
再看两个矩阵的除法和矩阵的数乘,使用运算符"/","*"。
mat1 = np.arange(1,11).reshape(2,5)
mat2 = np.arange(4,14).reshape(2,5)
mat3 = mat1/mat2 # 矩阵对应元素相除
mat4 = mat1*0.5 # 矩阵的数乘
print(mat3, mat4, sep='\n')
程序输出的结果如下:
[[0.25       0.4        0.5        0.57142857 0.625     ]
 [0.66666667 0.7        0.72727273 0.75       0.76923077]]
[[0.5 1.  1.5 2.  2.5]
 [3.  3.5 4.  4.5 5. ]]
再看取余除法和取商除法,分别使用运算符"%","//"。
mat1 = np.arange(1,16).reshape(3,5)
mat2 = np.full((3,5), 3)
mat3 = mat1 % mat2 # 对应元素取余
mat4 = mat1//mat2 # 对应元素向下取整除法
print(mat3, mat4, sep='\n')
程序输出的结果如下:
[[1 2 0 1 2]
 [0 1 2 0 1]
 [2 0 1 2 0]]
[[0 0 1 1 1]
 [2 2 2 3 3]
 [3 4 4 4 5]]
比较两个矩阵元素的大小,返回大者或者小者元素,组成一个矩阵,使用函数np.fmax()或者(np.maximum()),和函数np.fmin()或者是(np.minimum()),执行下面的代码:
mat1 = np.array([1,4,5,6,2,8]).reshape(2,3)
mat2 = np.array([0,3,6,9,1,3]).reshape(2,3)
mat3 = np.fmax(mat1, mat2) # 取最大者元素
mat4 = np.fmin(mat1, mat2) # 取最小者元素
print(mat1, mat2, mat3, mat4, sep='\n')
程序输出的结果如下:
[[1 4 5]
 [6 2 8]]
[[0 3 6]
 [9 1 3]]
[[1 4 6]
 [9 2 8]]
[[0 3 5]
 [6 1 3]]
两个矩阵之间元素的大小比较,直接使用比较运算符"<, <=, >, >=, ==, !="即可。返回的是逻辑数组,由True和False组成的数组。可以用作下标来索引数组元素,执行下面的元素:
mat1 = np.arange(10).reshape(2,5)
mat2 = np.array([2,1,4,9,8,0,12,8,8,6]).reshape(2,5)
mat3 = mat1 < mat2
mat4 = mat1 <= mat2
mat5 = mat1 == mat2
mat6 = mat1[mat3] # 取出mat1中小于mat2对应元素的元素
mat7 = mat1[np.logical_not(mat3)] # 取出mat1中大于等于mat2对应元素的元素
mat8 = mat1[mat4] # 取出mat1中小于等于mat2对应元素的元素
mat9 = mat1[mat5] # 取出mat1中等于mat2对应元素的元素
print(mat6, mat7, mat8, mat9, sep='\n')
输出的结果如下:
[0 2 3 4 6 7]
[1 5 8 9]
[0 1 2 3 4 6 7 8]
[1 8]
上面使用到了一个对矩阵元素取非的函数np.logical_not(),下面就展开说说矩阵的逻辑符运算。使用函数np.logical_and()对两个矩阵的对应元素取“且”,意思是若两个元素都非零,则返回的元素是True,否则为False。函数np.logical_or()对两个矩阵的对应元素取“或”,意思是若两个元素都为零,则返回的元素是False,否则为True。执行下面代码:
mat1 = np.zeros((2,4))
mat2 = np.array([[0,1,2,3],[3,2,1,0]])
mat3 = np.logical_and(mat1, mat2) # 取且
mat4 = np.logical_or(mat1, mat2) # 取或
mat5 = np.logical_not(mat2) # 取反
print(mat3, mat4, mat5, sep='\n')
程序输出的结果如下:
[[False False False False]
 [False False False False]]
[[False  True  True  True]
 [ True  True  True False]]
[[ True False False False]
 [False False False  True]]
特别需要注意的是,这里不能使用运算符"&, |"以及关键字"not"代替上面的三个函数。
计算两个矩阵对应元素的最小公倍数和最大公因子,分别使用函数"np.lcm()","np.gcd()",执行下面的代码:
mat1 = np.array([1,3,5,6,7,8]).reshape(2,3)
mat2 = np.arange(1,7).reshape(2,3)
mat3 = np.gcd(mat1, mat2) # 最大公因子
mat4 = np.lcm(mat1, mat2) # 最小公倍数
print(mat1, mat2, mat3, mat4, sep='\n')
程序输出的结果如下:
[[1 3 5]
 [6 7 8]]
[[1 2 3]
 [4 5 6]]
[[1 1 1]
 [2 1 2]]
[[ 1  6 15]
 [12 35 24]]
将向量转化为对角矩阵,使用函数"np.diag()",执行下面的代码:
vec = np.arange(5)
mat = np.diag(vec)
print(vec, mat, sep='\n')
程序输出的结果如下:
[0 1 2 3 4]
[[0 0 0 0 0]
 [0 1 0 0 0]
 [0 0 2 0 0]
 [0 0 0 3 0]
 [0 0 0 0 4]]
将对角矩阵的对角元素拉直为向量,仍然是使用函数"np.diag()",执行下面的代码:
mat = np.identity(4)
vec = np.diag(mat)
print(vec)
程序输出的结果如下:
[1. 1. 1. 1.]
将矩阵拉直为向量,不能使用函数,只能使用方法"mat.flatten()",其中的"mat"是矩阵名,执行下面的代码:
mat = np.arange(6).reshape(2,3)
vec = mat.flatten()
print(vec)
程序输出的结果如下:
[0 1 2 3 4 5]
矩阵的数学函数
矩阵的数学函数,是指将数学函数应用在矩阵的每一个元素上。数学函数有很多,比如三角函数,对数函数,指数函数,反三角函数等。这些函数地对向量或者标量都适用的。
对矩阵元素取相反数,使用函数np.negative()或者符号"-",执行下面的代码:
mat1 = np.arange(-5,5).reshape(2,5)
mat2 = np.negative(mat1) # 或者是 mat2 = -mat1
print(mat2)
程序输出的结果如下:
[[ 5  4  3  2  1]
 [ 0 -1 -2 -3 -4]]
对矩阵元素取绝对值,使用函数np.abs(),执行下面的代码:
mat1 = np.arange(-5,5).reshape(2,5)
mat2 = np.absolute(mat1) # 或者使用内置函数 abs(mat1)
print(mat2)
程序输出的结果如下:
[[5 4 3 2 1]
 [0 1 2 3 4]]
对矩阵元素应用符号函数,使用函数np.sign(),执行下面的代码:
mat1 = np.arange(-5,5).reshape(2,5)
mat2 = np.sign(mat1)
print(mat2)
程序输出的结果如下:
[[-1 -1 -1 -1 -1]
 [ 0  1  1  1  1]]
对矩阵元素向下取整,使用函数np.floor(),执行下面的代码:
start = 1
end = 10
num_point = 6
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True)
# 通过起始点和线性点列的个数生成一个数列
mat2 = np.floor(mat1)
print(mat1, mat2, sep='\n')
程序输出的结果如下:
[ 1.   2.8  4.6  6.4  8.2 10. ]
[ 1.  2.  4.  6.  8. 10.]
对矩阵元素向上取整,使用函数np.ceil(),执行下面的代码:
start = 1
end = 10
num_point = 6
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True)
mat2 = np.ceil(mat1)
print(mat2)
程序输出的结果如下:
[ 1.  3.  5.  7.  9. 10.]
对矩阵元素就近取整,使用函数np.rint(),执行下面的代码:
start = -4
end = 4
num_point = 6
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True)
mat2 = np.rint(mat1)
print(mat1, mat2, sep='\n')
它是先不管正负号,取最近的整数,然后加上正负号。程序输出的结果如下:
[-4.  -2.4 -0.8  0.8  2.4  4. ]
[-4. -2. -1.  1.  2.  4.]
对矩阵元素截尾取整,使用函数np.trunc(),执行下面的代码:
start = -4
end = 4
num_point = 6
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True)
mat2 = np.trunc(mat1)
print(mat2)
程序输出的结果如下:
[-4. -2. -0.  0.  2.  4.]
对矩阵元素取三角函数,可以分别使用函数np.sin(),np.cos(),np.tan(),执行下面的代码:
start = -np.pi
end = np.pi # 圆周率
num_point = 12
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True).reshape(3,4)
mat2 = np.sin(mat1)
mat3 = np.cos(mat1)
mat4 = np.tan(mat1)
print(mat2, mat3, mat4, sep='\n')
程序输出的结果如下:
[[-1.22464680e-16 -5.40640817e-01 -9.09631995e-01 -9.89821442e-01]
 [-7.55749574e-01 -2.81732557e-01  2.81732557e-01  7.55749574e-01]
 [ 9.89821442e-01  9.09631995e-01  5.40640817e-01  1.22464680e-16]]
[[-1.         -0.84125353 -0.41541501  0.14231484]
 [ 0.65486073  0.95949297  0.95949297  0.65486073]
 [ 0.14231484 -0.41541501 -0.84125353 -1.        ]]
[[ 1.22464680e-16  6.42660977e-01  2.18969456e+00 -6.95515277e+00]
 [-1.15406152e+00 -2.93626493e-01  2.93626493e-01  1.15406152e+00]
 [ 6.95515277e+00 -2.18969456e+00 -6.42660977e-01 -1.22464680e-16]]
对矩阵元素取反三角函数,可以分别使用函数np.arcsin(),np.arccos(),np.arctan(),执行下面的代码:
start = -1
end = 1
num_point = 12
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=True).reshape(3,4)
mat2 = np.arcsin(mat1)
mat3 = np.arccos(mat1)
mat4 = np.arctan(mat1)
print(mat2, mat3, mat4, sep='\n')
程序输出的结果如下:
[[-1.57079633 -0.95824159 -0.689775   -0.47186184]
 [-0.27622663 -0.09103478  0.09103478  0.27622663]
 [ 0.47186184  0.689775    0.95824159  1.57079633]]
[[3.14159265 2.52903792 2.26057133 2.04265816]
 [1.84702296 1.6618311  1.47976155 1.2945697 ]
 [1.09893449 0.88102133 0.61255474 0.        ]]
[[-0.78539816 -0.68572951 -0.56672922 -0.42662749]
 [-0.26625205 -0.09065989  0.09065989  0.26625205]
 [ 0.42662749  0.56672922  0.68572951  0.78539816]]
对矩阵元素取双曲函数,可以分别使用函数np.sinh(),np.cosh(),np.tanh(),执行下面的代码:
mat1 = np.arange(-4,6).reshape(2,5)
mat2 = np.sinh(mat1)
mat3 = np.cosh(mat1)
mat4 = np.tanh(mat1)
print(mat2, mat3, mat4, sep='\n')
程序输出的结果如下:
[[-27.2899172  -10.01787493  -3.62686041  -1.17520119   0.        ]
 [  1.17520119   3.62686041  10.01787493  27.2899172   74.20321058]]
[[27.30823284 10.067662    3.76219569  1.54308063  1.        ]
 [ 1.54308063  3.76219569 10.067662   27.30823284 74.20994852]]
[[-0.9993293  -0.99505475 -0.96402758 -0.76159416  0.        ]
 [ 0.76159416  0.96402758  0.99505475  0.9993293   0.9999092 ]]
对矩阵元素取反双曲函数,可以分别使用函数np.arcsinh(),np.arccosh(),np.arctanh(),执行下面的代码:
mat1 = np.arange(-4,6).reshape(2,5)
mat2 = np.arange(1,7).reshape(2,3)
start = -0.95
end = 1
num_point = 12
mat3 = np.linspace(start=start, stop=end, num=num_point, endpoint=False).reshape(3,4)
mat4 = np.arcsinh(mat1)
mat5 = np.arccosh(mat2)
mat6 = np.arctanh(mat3)
print(mat4, mat5, mat6, sep='\n')
程序输出的结果如下:
[[-2.09471255 -1.81844646 -1.44363548 -0.88137359  0.        ]
 [ 0.88137359  1.44363548  1.81844646  2.09471255  2.31243834]]
[[0.         1.3169579  1.76274717]
 [2.06343707 2.29243167 2.47788873]]
[[-1.83178082 -1.06481564 -0.73316853 -0.50048691]
 [-0.3095196  -0.1383765   0.02500521  0.18974481]
 [ 0.36544375  0.56611445  0.81987163  1.21274161]]
对矩阵元素取自然对数,使用函数np.log(),取自然指数,使用函数np.exp(),执行下面的代码:
start = 0.1
end = 4
num_point = 12
mat1 = np.linspace(start=start, stop=end, num=num_point, endpoint=False).reshape(3,4)
mat2 = np.log(mat1)
mat3 = np.exp(mat2)
print(mat2, mat3, sep='\n')
程序输出的结果如下:
[[-2.30258509 -0.85566611 -0.28768207  0.07232066]
 [ 0.33647224  0.54522705  0.71783979  0.86499744]
 [ 0.99325177  1.10691109  1.20896035  1.30155313]]
[[0.1   0.425 0.75  1.075]
 [1.4   1.725 2.05  2.375]
 [2.7   3.025 3.35  3.675]]
对矩阵元素开根号,取三次方根,可以分别使用函数np.sqrt(),np.cbrt(),执行下面的代码:
mat1 = np.arange(1,11).reshape(2,5)
mat2 = np.sqrt(mat1)
mat3 = np.cbrt(mat1)
print(mat2, mat3, sep='\n')
程序输出的结果如下:
[[1.         1.41421356 1.73205081 2.         2.23606798]
 [2.44948974 2.64575131 2.82842712 3.         3.16227766]]
[[1.         1.25992105 1.44224957 1.58740105 1.70997595]
 [1.81712059 1.91293118 2.         2.08008382 2.15443469]]
对矩阵元素取次幂,可以使用运算符"**",执行下面的代码:
mat1 = np.arange(1,11).reshape(2,5)
mat2 = mat1**2
mat3 = mat1**3
print(mat2, mat3, sep='\n')
程序输出的结果如下:
[[  1   4   9  16  25]
 [ 36  49  64  81 100]]
[[   1    8   27   64  125]
 [ 216  343  512  729 1000]]
存储和读取矩阵
所谓存储和读取矩阵,就是将矩阵存储为一个特定格式的文件。读取就是将上面存储的特定格式的文件读取为矩阵。存储矩阵为文件和将文件读取为矩阵,分别使用函数np.save()以及np.load()。
执行下面的代码:
mat = np.identity(3)
np.save('./data/identity.npy', mat) # 存储为.npy格式的二进制文件
然后将这个文件读取出来,还原为矩阵,执行下面的代码:
mat = np.load('./data/identity.npy')
print(mat)
程序输出的结果如下:
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
也可以将矩阵存储为文本文件,分别使用函数np.savetxt(),和np.loadtxt()。执行下面的代码:
mat1 = np.arange(12).reshape(3,4)
np.savetxt("./data/matrix.txt", mat1)
mat2 = np.loadtxt("./data/matrix.txt")
print(mat2)
程序输出的结果如下:
[[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]

 [ 8.  9. 10. 11.]]

以上就是python矩阵教程(Python矩阵的创建和运算)的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取