【第8章 数据分析基础】逐元素乘法、矩阵乘法(矩阵积)、向量点乘(点积)、向量叉乘(叉积)的全面辨析
这是一个常见的概念混淆。下面我们从 定义、用途、计算方式、NumPy 实现 四个角度彻底厘清:
一、先说结论(一句话总结)
| 名称 | 是否存在? | 正确术语 | 对应 NumPy 操作 |
|---|---|---|---|
| 矩阵乘法 | ✅ 存在 | 矩阵乘积(Matrix Multiplication) | A @ B 或 np.dot(A, B) |
| 矩阵叉乘 | ❌ 不存在 | 叉乘仅针对向量(通常是3D) | np.cross(a, b)(仅用于向量) |
🔑 叉乘(cross product)是向量运算,不是矩阵运算。
你不能对两个普通矩阵做“叉乘”。
二、什么是矩阵乘法?(Matrix Multiplication)
定义:
给定矩阵 ( A \in \mathbb{R}^{m \times n} ) 和 ( B \in \mathbb{R}^{n \times p} ),
它们的矩阵乘积 ( C = AB ) 是一个 ( m \times p ) 的矩阵,其中:
[
C_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj}
]
示例:
import numpy as np
A = np.array([[1, 2],
[3, 4]]) # (2,2)
B = np.array([[5, 6],
[7, 8]]) # (2,2)
C = A @ B # 或 np.dot(A, B)
print(C)
# 输出:
# [[19 22] # 1*5 + 2*7 = 19, 1*6 + 2*8 = 22
# [43 50]] # 3*5 + 4*7 = 43, 3*6 + 4*8 = 50
import numpy as np
# 示例1:2×2矩阵 × 2×3矩阵(列数2=行数2,满足要求)
A = np.array([[1, 2], [3, 4]]) # 形状:(2,2)(2行2列)
B = np.array([[5, 6, 7], [8, 9, 10]]) # 形状:(2,3)(2行3列)
C = A @ B # 等价于np.matmul(A, B)
print("矩阵乘法结果(A@B):")
print(C)
# 计算逻辑:
# 第1行第1列:1×5 + 2×8 = 5 + 16 = 21
# 第1行第2列:1×6 + 2×9 = 6 + 18 = 24
# 第1行第3列:1×7 + 2×10 = 7 + 20 = 27
# 第2行第1列:3×5 + 4×8 = 15 + 32 = 47
# 第2行第2列:3×6 + 4×9 = 18 + 36 = 54
# 第2行第3列:3×7 + 4×10 = 21 + 40 = 61
# 输出:
# [[21 24 27]
# [47 54 61]]
# 示例2:向量与矩阵的矩阵乘法(向量可视为1行n列或n行1列的矩阵)
x = np.array([1, 2]) # 形状:(2,),可视为(1,2)的行向量
D = x @ A # x是(1,2),A是(2,2),结果为(1,2)的行向量
print("\n向量×矩阵的矩阵乘法结果:", D) # 计算:1×1+2×3=7,1×2+2×4=10 → 输出:[ 7 10]
关键提醒:矩阵乘法不满足交换律,即 A@B ≠ B@A(除非是特殊矩阵如方阵),这与逐元素乘法完全不同。
✅ 这是线性代数中最基础、最重要的运算之一,用于:
- 线性变换复合
- 神经网络全连接层
- 坐标变换等
三、什么是叉乘?(Cross Product)
首先明确:向量叉乘(Cross Product)是「三维向量特有的运算」,结果是一个「垂直于两个输入向量的新向量」,而非元素级运算(与点积、哈达玛积完全不同)。
1. 数学定义(三维向量)
设两个三维向量:
a = (a1, a2, a3)b = (b1, b2, b3)
叉乘结果 a × b 是一个向量,计算公式为:
a × b = (a2*b3 - a3*b2, a3*b1 - a1*b3, a1*b2 - a2*b1)
几何意义:新向量的长度 = 两个向量长度的乘积 × 夹角正弦值(即平行四边形面积),方向由右手定则确定。
2. NumPy 中的叉乘实现
NumPy 用 np.cross(a, b) 实现向量叉乘,必须保证输入是三维向量(1D 数组长度为 3,或 2D 数组每行是三维向量)。
代码示例:
import numpy as np
# 1. 两个三维向量(1D 数组)
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
cross = np.cross(a, b)
print(cross) # 输出:[-3 6 -3](按公式计算验证:2*6-3*5=-3,3*4-1*6=6,1*5-2*4=-3)
# 2. 多个三维向量(2D 数组,每行是一个向量)
a = np.array([[1,2,3], [4,5,6]])
b = np.array([[7,8,9], [10,11,12]])
cross = np.cross(a, b)
print(cross) # 输出:[[-3 6 -3], [-3 6 -3]]
关键注意:
- 若输入不是三维向量(如 2D 向量),
np.cross会自动补 0 成三维((x,y) → (x,y,0)),但结果可能不符合预期,需谨慎使用; - 叉乘不满足交换律:
np.cross(a, b) = -np.cross(b, a)(方向相反)。
四、为什么会有“矩阵叉乘”的误解?
可能源于以下混淆:
| 混淆点 | 正确理解 |
|---|---|
| “叉乘看起来像乘法” | 叉乘是特殊向量运算,和普通乘法、矩阵乘法都不同 |
| “3×3 矩阵和向量有关” | 旋转矩阵可以表示叉乘的线性变换,但矩阵本身不做叉乘 |
| 中文口语说“矩阵相乘”泛指 | 技术上,“矩阵乘法”特指 matrix multiplication |
五、NumPy 中的对应操作速查
| 数学运算 | NumPy 写法 | 输入要求 |
|---|---|---|
| 逐元素乘法 | A * B |
形状可广播 |
| 矩阵乘法 | A @ B 或 np.dot(A, B) |
A 列数 = B 行数 |
| 向量点积 | np.dot(a, b) 或 a @ b |
向量长度相同 |
| 向量叉乘 | np.cross(a, b) |
向量长度为 2 或 3 |
六、总结
- ✅
x * x和x ** 2等价,都是元素级平方,可互换; - ✅ 矩阵乘法:存在,是标准线性代数运算,用
@或np.dot。 - ❌ 矩阵叉乘:不存在。叉乘只作用于向量(尤其是 3D 向量)。
- 🔄 如果你有一批 3D 向量(形状
(N,3)),可以用np.cross批量计算,但这仍是向量叉乘的批量版,不是“矩阵叉乘”。
非常好的问题!“点积”、“点乘”、“矩阵乘法”这几个术语在不同语境下容易混淆。下面我们从数学定义、NumPy 实现、相互关系三个层面彻底厘清:
✅ 一句话总结
| 术语 | 是否等价? | 说明 |
|---|---|---|
| 点积 = 点乘 | ✅ 是 | 两者是同一概念的不同叫法(dot product) |
| 点积 = 矩阵乘法? | ⚠️ 部分情况是 | 当两个向量做矩阵乘法时,结果等于点积;但矩阵乘法范围更广 |
一、点积(Dot Product) = 点乘
✔ 定义:
给定两个相同长度的向量 (\mathbf{a}, \mathbf{b} \in \mathbb{R}^n),
它们的点积(也叫内积、标量积)是一个标量(单个数):
[
\mathbf{a} \cdot \mathbf{b} = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n = \sum_{i=1}^{n} a_i b_i
]
✔ NumPy 实现:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 以下三种写法等价:
result1 = np.dot(a, b)
result2 = a @ b # Python 3.5+ 推荐
result3 = np.sum(a * b) # 手动实现
print(result1) # 32 → 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
✅ “点积”和“点乘”完全等价,只是中文习惯不同:“点积”强调结果是“积”,“点乘”强调运算形式像“乘”。
二、点积 和 矩阵乘法 的关系
🔑 核心结论:
两个向量的点积,可以看作是矩阵乘法的一个特例。
📌 具体来说:
假设:
- (\mathbf{a}) 是列向量(shape
(n, 1)) - (\mathbf{b}) 是列向量(shape
(n, 1))
那么:
- (\mathbf{a}^\top \mathbf{b})(行向量 × 列向量)是一个 1×1 矩阵,其值等于点积;
- 在 NumPy 中,如果你用
a @ b且a,b都是 1D 数组,NumPy 会自动按向量点积处理。
✅ 示例:
a = np.array([1, 2, 3]) # shape (3,) → 1D 向量
b = np.array([4, 5, 6]) # shape (3,)
print(a @ b) # 32 → 点积(标量)
# 如果显式转为 2D:
a_col = a.reshape(-1, 1) # (3,1)
b_row = b.reshape(1, -1) # (1,3)
print(b_row @ a_col) # → 1x1 矩阵,值为点积
❌ 但注意:
- 如果你用两个 2D 矩阵相乘(如
(2,3) @ (3,4)),这是普通矩阵乘法,结果是(2,4)矩阵,不是点积。 - 点积只针对两个向量,结果是标量;矩阵乘法可作用于任意兼容维度的矩阵,结果通常是矩阵。
三、对比总结表
| 运算 | 输入要求 | 输出类型 | NumPy 写法 | 是否等价 |
|---|---|---|---|---|
| 点积 / 点乘 | 两个等长向量(1D 或 (n,)) |
标量 | np.dot(a,b) 或 a @ b |
✅ 点积 = 点乘 |
| 矩阵乘法 | A: (m,n), B: (n,p) |
(m,p) 矩阵 |
A @ B 或 np.dot(A,B) |
⚠️ 点积是其特例(当 m=p=1) |
| 逐元素乘法 | 形状可广播 | 同形状数组 | A * B |
❌ 完全不同 |
四、常见误区澄清
❌ 误区1:“点乘就是 *”
→ 错!a * b 是逐元素相乘,结果还是向量:
a = [1,2,3]; b = [4,5,6]
a * b → [4,10,18] # 不是 32!
❌ 误区2:“所有 @ 都是点积”
→ 错!@ 是通用矩阵乘法运算符:
- 对 1D 数组:执行点积(返回标量)
- 对 2D+ 数组:执行标准矩阵乘法(返回矩阵)
✅ 正确认知:
- 点积 = 向量之间的特殊矩阵乘法
- 矩阵乘法 ⊃ 点积(点积是子集)
五、实际应用场景
| 场景 | 用什么? | 为什么? |
|---|---|---|
| 计算两个特征向量的相似度 | a @ b |
点积衡量方向一致性 |
| 神经网络全连接层 | X @ W |
矩阵乘法批量计算线性组合 |
| 求向量长度平方 | v @ v |
点积自身 = ∥v∥² |
✅ 终极总结
- 点积 = 点乘:✅ 完全等价,都是
a · b = Σ aᵢbᵢ,结果是标量。 - 点积 是 矩阵乘法的特例:✅ 当两个向量以“行×列”形式相乘时,矩阵乘法退化为点积。
- 但矩阵乘法 ≠ 点积:❌ 矩阵乘法适用范围更广,结果通常是矩阵。
🧠 记住口诀:
“点乘点积一回事,矩阵乘法包罗它;
向量相乘得标量,矩阵相乘得矩阵。”
这样你就再也不会混淆啦!
📌 记住:
“叉乘属于向量,矩阵只有乘法(和转置、求逆等)。”
这样就不会再混淆啦!

浙公网安备 33010602011771号