2.2.1 创建 NumPy 矩阵
在NumPy中,矩阵是 ndarray 的子类,且数组和矩阵有着重要的区别。NumPy 提供了两个基本的对象,分别是N维数组对象和通用函数对象,其他对象都是在它们的基础上继承的。矩阵继承自 NumPy数组对象的二维数组对象。与数学概念中的矩阵一样,NumPy中的矩阵也是二维的。读者可使用 mat、matrix 和bmat 函数来创建矩阵。
当使用 mat 函数创建矩阵时,如果输入 matrix 或 ndarray 对象,那么不会创建相应副本。因此,调用 mat 函数和调用matrix函数等价,如代码2-30所示。
代码 2-30 使用mat函数与matrix函数创建矩阵
import numpy as np #导人 NumPy库
matrl = np.mat('123;456;789')#使用分号隔开数据
print('创建的矩阵为:\n',matr1)
创建矩阵的结果为:
[ [1 2 3 ]
[4 5 6 ]
[7 8 9 ] ]
matr2 = np.matrix([[1,2,3], [4,5,6], [7,8,9]]
print('创建的矩阵为: \n',matr2)
创建的矩阵为:
[ [1 2 3 ]
[4 5 6 ]
[7 8 9 ] ]
在大多数情况下,用户会根据小的矩阵来创建大的矩阵,即将小矩阵组合成大矩阵。
在 NumPy 中,可以使用bmat 分块矩阵(Block Matrix)函数实现,如代码2-31所示。
代码2-31 使用bmat函数创建矩阵
arr1 = np.eye(3)
print('创建的数组 arr1 为: \n', arr1)
创建的数组 arr1 为:
[ [ 1. 0. 0. ]
[ 0. 1. 0. ]
[ 0. 0. 1. ] ]
arr2 = 3 * arr1
print('创建的数组arr2为: \n, arr2)
创建的数组 arr2 为:
[ [ 3. 0. 0. ]
[ 0. 3. 0. ]
[ 0. 0. 3. ] ]
print('创建的矩阵为: \n', np.bmat('arr1 arr2; arr1 arr2'))
创建的矩阵为:
[ [ 1. 0. 0. 3. 0. 0. ]
[ 0. 1. 0. 0. 3. 0. ]
[ 0. 0. 1. 0. 0. 3. ]
[ 1. 0. 0. 3. 0. 0. ]
[ 0. 1. 0. 0. 3. 0. ]
[ 0. 0. 1. 0. 0. 3. ] ]
在 NamPy 中,矩阵运算是针对整个矩阵中的每个元素进行的。与使用 for 循环相比,其在运算速度上更快,如代码 2-32所示。
matrl = np.mat ('1 2 3; 4 5 6 ; 7 8 9') #创建矩阵
print(;创建矩阵为: \n', matr1)
创建的矩阵为:
[ [1 2 3]
[4 5 6]
[7 8 9] ]
matr2 = matr1 * 3 #矩阵与数相乘
print('矩阵与数相乘结果为: \n', matr2)
矩阵与数相乘结果为:
[ [ 3 6 9 ]
[ 12 15 18 ]
[ 21 24 27] ]
print('矩阵相加结果为: \n', matr1 + matr2) #矩阵相加
矩阵相加结果为:
[ [ 4 8 12 ]
[16 20 24]
[28 32 36] ]
print('矩阵相减结果为: \n', matr1 + matr2) #矩阵相减
矩阵相减结果为:
[ [ -2 -4 -8 ]
[ -8 -10 -12]
[-14 -16 -18] ]
print('矩阵相乘结果为:\n',matr1 * matr2)#矩阵相乘
矩阵相乘结果为:
[ [ 90 108 126]
[198 243 288]
[306 378 450] ]
除了能够实现各类运算外,矩阵还有其特有的属性,如表2-9所示
表2-9 短阵特有属性及其说明
属性名称 | 属性说明 |
T | 返回自身的转置矩阵 |
H | 返回自身的共轭转置矩阵 |
I | 返回自身的逆矩降 |
A | 返回自身数据的二维数组 |
矩阵属性的具体查看方法如代码 2-33所示。
代码 2-33查看矩阵属性
matr3 = np.mat ([[6, 2, 1], [1, 5, 2], [3, 4, 8]])
print('矩阵转置结果为: \n', matr3.T) #转置矩阵
#共轭转置矩阵(实数矩阵的共轭转置就是其本身)
print('矩阵共轭转置结果为:\n',matr3.H)
print('矩阵的逆矩阵结果:\n',matr3.工)#逆矩阵
print('矩阵的二维数组结果:\n',matr3.A)#返回二维数组的视图
矩阵装置结果为: [[6 1 3] [2 5 4] [1 2 8]] 矩阵共轭装置结果为: [[6 1 3] [2 5 4] [1 2 8]] 矩阵逆矩阵结果为: [[ 0.18079096 -0.06779661 -0.00564972] [-0.01129944 0.25423729 -0.06214689] [-0.06214689 -0.10169492 0.15819209]] 矩阵的二维数组结果为: [[6 2 1] [1 5 2] [3 4 8]]
2.2.2 掌握ufunc函数
常用的 ufunc 函数运算有四则运算、比较运算和逻辑运算等。
ufunc 函数支持四则运算,并且保留运算符。unfunc 函数运算和数值运算的使用方式-样。但是需要注意的是,ufunc 函数操作的对象是数组。数组间的四则运算表示对数组中的吗
每个元素分别进行四则运算,因此四则运算的两个数组的形状必须相同,如代码2-34所示
代码2-34 数组的四则运算
# 代码2-34
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print('数组相加结果为: ', x+y) # 数组相加
print('数组相减结果为: ',x - y) #数组相减
print('数组相乘结果为: ', x * y) #数组相乘
print('数组相除结果为: ', x/y) # 数组相除
print('数组幂运算结果为: ', x ** y) #数组幂运算
数组相加结果为: [5 7 9] 数组相减结果为: [-3 -3 -3] 数组相乘结果为: [ 4 10 18] 数组相除结果为: [0.25 0.4 0.5 ] 数组幂运算结果为: [ 1 32 729]
在ufiane 两數中也支持究整的比般运算,>、<、一、三、、下。比较运雞返国的錦果是一个布尔型数组,其每个元素约数组对应元素的比较结果,如代码2-35所示
代码2-35数组的比较运算
# 2-35
x = np.array([1,2,5])
y = np.array([2,3,4])
print('数组比较结果为: ', x < y)
print('数组比较结果为: ', x > y)
print('数组比较结果为: ', x == y)
print('数组比较结果为: ', x >= y)
print('数组比较结果为: ', x <= y)
print('数组比较结果为: ', x != y)
数组比较结果为: [ True True False] 数组比较结果为: [False False True] 数组比较结果为: [False False False] 数组比较结果为: [False False True] 数组比较结果为: [ True True False] 数组比较结果为: [ True True True]
在 NumEy逻徘运第中,numpy.all函数用于测试所有数组元素的计算结果为TNO,numpyany 两数用于测试任何数组元素的计算结果是否为 Tnue,如代码2-36所示
代码2-36 数组的逻辑运算
# 代码2-36
print('数组逻辑运算结果为: ', np.all(x == y))
print('数组逻辑运算结果为: ',np.any(x == y))
数组逻辑运算结果为: False 数组逻辑运算结果为: False
2. ufunc 函数的广播机制
广播(Broadcasting)机制是指不同形状的数组之间执行算术运算的方式。当使用ufunc函数进行数组计算时,ufumc函数会对两个数组的对应元素进行计算。进行这种计算的前提是两个数组的形状一致。如果两个数组的形状不一致,那么NumPy会实行广播机制。NomF中的广播机制并不容易理解,特别是在进行高维数组计算的时候。为了更好地使用广播机制,需要遵循以下4个原则。
(1)让所有的输入数组向其中 shape 最长的数组看齐,如果数组中 shape 不足,那么通过在前面加1补齐。
(2)输出数组的 shape 是输入数组 shape 在各个轴上的最大值的组合。
(3)如果输入数组的某个轴的长度和输出数组的对应轴的长度相同,或输人数组的某个轴的长度为1,那么这个数组能够用于计算,否则系统将会出错。
(4)当输入数组的某个轴的长度为1时,将使用此轴上的第一组值进行运算。
以一维数组和二维数组为例说明广播机制的运算方法。一维数组的广播机制如代码2-37所示。
代码2-37一堆数组的广播机制
# 2-37
arrl = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
print('创建的数组arrl为: \n', arrl)
print('数组arrl的形状为: ', arrl.shape)
arr2 = np.array([1, 2, 3])
print('创建的数组arr2为: ', arr2)
print('数组arr2的形状为: ', arr2.shape)
print('数组相加结果为: \n', arrl + arr2)
创建的数组arrl为: [[0 0 0] [1 1 1] [2 2 2] [3 3 3]] 数组arrl的形状为: (4, 3) 创建的数组arr2为: [1 2 3] 数组arr2的形状为: (3,) 数组相加结果为: [[1 2 3] [2 3 4] [3 4 5] [4 5 6]]
二维数组的广播机制如代码2-38所示。
代码 2-38 二维数组的广播机制
# 2-38
arr1 = np.array([[0, 0, 0],[1, 1, 1], [2, 2, 2], [3, 3, 3]])
print('创建的数组arr1为: \n',arr1)
print('数组arr1的形状为: ',arr1.shape)
arr2 = np.array([1, 2, 3, 4]).reshape((4,1))
print('创建的数组arr2为: \n',arr2)
print('数组arr2的形状为: ',arr2.shape)
print('数组相加结果为: \n',arr1 + arr2)
创建的数组arr1为: [[0 0 0] [1 1 1] [2 2 2] [3 3 3]] 数组arr1的形状为: (4, 3) 创建的数组arr2为: [[1] [2] [3] [4]] 数组arr2的形状为: (4, 1) 数组相加结果为: [[1 1 1] [3 3 3] [5 5 5] [7 7 7]]