一、定义
矩阵乘法是线性代数中的一个基本运算,它定义了两个矩阵之间如何相乘。给定两个矩阵A和B,如果A的列数等于B的行数,那么这两个矩阵就可以相乘。结果矩阵C的元素由A的第i行和B的第 j列的对应元素的点积(内积)计算得出。
二、方法
在Python中,矩阵乘法可以通过以下几种方法实现:
1、x * y
(1)语法:x*y
(2)特点:当使用 * 运算符对数组进行乘法时,默认执行的是逐元素乘法(Hadamard product),即两个数组对应位置的元素相乘。而当 * 运算符用于 np.matrix 对象时,它执行的是矩阵乘法,这是一种线性代数中的乘法,遵循矩阵乘法的规则,即第一个数组的列数必须与第二个数组的行数相等。
(3)示例
import numpy as np
# 创建两个矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 元素对元素的乘法(Hadamard乘法)
C_hadamard = A * B
print("Hadamard乘法:\n", C_hadamard)
import numpy as np
x=np.matrix([[1, 2], [3, 4]])
y=np.matrix([[5, 6], [7, 8]])
result = x * y
print(result)
在NumPy中,np.matrix 和 np.array 是两种不同的数据结构,它们在内存中的存储方式和数学运算行为有所不同。np.matrix 是专门设计用来模拟MATLAB中矩阵的行为,而 np.array 是更通用的多维数组结构。当使用 * 运算符对数组进行乘法时,默认执行的是逐元素乘法(Hadamard product),即两个数组对应位置的元素相乘。而当 * 运算符用于 np.matrix 对象时,它执行的是矩阵乘法,这是一种线性代数中的乘法,遵循矩阵乘法的规则,即第一个数组的列数必须与第二个数组的行数相等。即上图输出第二个正确, * 运算符用于 np.matrix 对象才可输出正确结果。
2、使用 @ 运算符
(1)语法:x@y
(2)特点:从Python 3.5开始,@ 运算符被引入用于矩阵乘法,专门用于执行矩阵乘法操作。它支持二维数组(矩阵)和一维数组(向量)之间的乘法,并且可以处理高维数组的广播。在NumPy中,这个运算符等价于 numpy.matmul()。矩阵乘法的规则是,第一个矩阵的列数必须与第二个矩阵的行数相同。
(3)示例
import numpy as np
# 创建两个矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 使用 @ 运算符进行矩阵乘法
C_at = A @ B
print("使用@运算符:\n", C_at)
3、np.matmul(x, y)
(1)语法:np.matmul(x, y)
(2)特点:np.matmul(x, y)是专门用于矩阵乘法的函数,它支持对多维数组进行矩阵乘法,与 @ 运算符的功能相同,支持广播规则。
(3)示例
import numpy as np
# 创建两个矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 使用 np.matmul 函数进行矩阵乘法
C_matmul = np.matmul(A, B)
print("使用np.matmul函数:\n", C_matmul)
4、x.dot(y)
(1)语法:x.dot(y)
(2)适用数据类型: NumPy数组
(3)结果类型: NumPy数组
(4)特点:这是一个传统的NumPy函数,用于进行矩阵乘法。它的功能与 np.matmul() 类似,通常用于一维和二维数组的乘法。对于一维数组,x.dot(y) 返回的是内积,而对于二维数组,则返回矩阵乘法的结果。x.dot(y) 用于矩阵乘法时,需要确保 x 和 y 的维度是兼容的。对于矩阵乘法,如果 x 是一个 m x n 的矩阵,而 y 是一个 n x p 的矩阵,那么结果将是一个 m x p 的矩阵。
(5)示例
import numpy as np
# 创建两个矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 使用dot方法进行矩阵乘法
C_dot = A.dot(B)
print("使用dot方法:\n", C_dot)
三、相关代码及输出
import numpy as np
# 创建两个NumPy数组,它们可以用于矩阵乘法
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 创建两个NumPy矩阵对象,用于Hadamard乘积
x=np.matrix([[1, 2], [3, 4]])
y=np.matrix([[5, 6], [7, 8]])
# 当*运算符用于np.matrix对象时,它执行的是矩阵乘法
C_hadamard = x * y
print("Hadamard乘法:\n", C_hadamard)
# 使用 @ 运算符进行矩阵乘法
C_at = A @ B
print("使用@运算符:\n", C_at)
# 使用 np.matmul 函数进行矩阵乘法
C_matmul = np.matmul(A, B)
print("使用np.matmul函数:\n", C_matmul)
# 使用dot方法进行矩阵乘法
C_dot = A.dot(B)
print("使用dot方法:\n", C_dot)
(1)对于 * 运算符(Hadamard乘法)、@ 运算符、np.matmul 函数和 dot 方法,输出结果将是:
四、矩阵乘法的应用
矩阵乘法在许多领域都有广泛的应用,包括:
(1)线性代数: 用于解线性方程组。
(2)计算机图形学: 用于变换坐标。在计算机图形学中,矩阵乘法用于表示和应用变换,如旋转、缩放、剪切和位移。一个3x3的变换矩阵可以被用来将一个点或一个对象从一个位置移动到另一个位置。
(3)机器学习: 用于计算权重和特征的组合。在机器学习中,矩阵乘法是许多算法的基础,包括线性回归、逻辑回归、神经网络和主成分分析(PCA)。矩阵乘法可以用于数据的转换、特征提取和降维。
(4)物理学: 用于描述状态变化。
五、与线性代数中矩阵乘法的异同
1、相同点
在Python中,无论是通过使用@运算符、np.matmul函数还是dot方法,得到的结果都与手动计算的结果一致。这证明了Python中实现的矩阵乘法与线性代数中矩阵乘法的数学原理是一致的。
2、不同点
(1)表示:在线性代数中,矩阵通常以抽象的数学符号表示,而在Python中,矩阵以具体的数据结构(如NumPy数组)表示。
(2)操作:在线性代数中,矩阵乘法是通过手工计算或使用数学软件进行的,而在Python中,矩阵乘法是通过函数调用 (如 dot、@ 运算符或 matmul)来实现的。
引申:高维数组的广播是指NumPy在进行数组操作时,能够自动将不同形状的数组进行扩展以匹配相同的形状。广播规则如下:
a、如果两个数组的维度数不相同,那么小维度数组的形状将会在左边补1。
b、对于每个维度,如果两个数组在该维度上的长度相同,或者其中一个数组在该维度上的长度为1,那么它们就是兼容的。
c、如果在任何维度上都不满足上述条件,则会引发错误。
d、广播之后,每个数组的行为就好像它的形状等于两个输入数组的形状的元素最大值。
e、在一个维度上,如果一个数组的长度为1,另一个数组的长度大于1,那么第一个数组的元素沿着该维度复制以匹配第二个数组的形状。
例如,假设我们有两个二维数组A和B,其中A的形状是(3, 1),B的形状是(1, 4)。根据广播规则,我们可以将A的形状扩展为(3, 4),使得它们可以进行矩阵乘法。具体来说,A的每一行都会与B的每一列相乘,得到一个新的矩阵C,其形状为(3, 4)。