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教程欢迎持续关注编程学习网。
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/11164/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料
查 看2022高级编程视频教程免费获取