A002.矩阵乘法🚩
文章目录
问题: NumPy中如何执行矩阵乘法,有哪些常用方法?
👇 点击展开/折叠 面试背诵模板(建议先背这个)
三种计算方式的直观对比
| 操作 | 语法 | 计算方式 | 示例 A(2,2) * B(2,2) |
|---|---|---|---|
| 逐元素乘 | A * B |
对应位置相乘 | [[1*5, 2*6], [3*7, 4*8]] |
| 矩阵乘 | A @ B |
行×列求和 | [[1*5+2*7, 1*6+2*8], [3*5+4*7, 3*6+4*8]] |
| 矩阵乘(函数) | np.matmul(A, B) |
同 @ |
同上 |
形状匹配核心规则
两个矩阵能做乘法,只看中间两个数字:
A(2行, 3列)乘B(3行, 4列)→ 中间的 3 必须相等,结果形状为 (2行, 4列)- 不满足则报错:
ValueError: shapes (2,3) and (5,4) not aligned
一维数组的特殊行为(注意点)
NumPy 的一维数组 (N,) 在矩阵乘中会被灵活处理:
1 | import numpy as np |
- 二维
@一维:右侧一维被视作列向量,结果降维为一维 - 一维
@二维:左侧一维被视作行向量,结果降维为一维
高维批量乘法(深度学习常用)
多个矩阵同时相乘时,@ 会保留前面的“批次维度”:
1 | A = np.random.rand(32, 2, 3) # 32个 2×3 矩阵 |
常见误区提醒
- 千万别用
*做矩阵乘,它是逐个位置相乘,不是线性代数里的乘法。 - 看到一维数组参与运算时,心里默认它没有行/列之分,结果也会丢掉行列,这是正常的。
- 大矩阵优先用
@或matmul,底层调 BLAS 库,速度比手写循环快成千上万倍。
🔥 第一关:先分清“两种乘法”(这是你混乱的根源)
| 符号 | 名字(土话) | 干什么用的? | 你的代码里是哪个? |
|---|---|---|---|
* (星号) |
“对应位相乘”(元素级乘法) | 两个表格同一位置的数字相乘。形状不同时,触发你刚学的广播机制(复印)。 | 你PPT里的 a * b 就是这个。 |
@ (或者 np.dot) |
“矩阵乘法”(线性代数乘法) | 左边表格的行 和 右边表格的列 做“搭配组合”。 | 你报错的 np3 @ np4 就是这个。 |
一句话救命:看见
*就想着 “一对一”;看见@就想着 “行对列,乘完求和”。
第二关:矩阵乘法(@)到底在算啥?(大白话+动图)
矩阵乘法不是对应位置相乘!它的规则是:“左行的元素,逐个去碰右列的元素,碰完加总。”
举个生活中的例子(卖菜记账本)
假设你是食堂采购员:
- 矩阵A(菜价表):3行(代表3个菜市场),2列(代表2种菜:土豆、西红柿)。
| 菜市场 | 土豆(元/斤) | 西红柿(元/斤) |
|---|---|---|
| 市场1 | 2 | 3 |
| 市场2 | 4 | 1 |
| 市场3 | 5 | 2 |
- 矩阵B(采购单):2行(2种菜),3列(代表周一到周三的采购量)。
| 菜品 | 周一(斤) | 周二(斤) | 周三(斤) |
|---|---|---|---|
| 土豆 | 1 | 4 | 2 |
| 西红柿 | 2 | 1 | 3 |
问:市场1在周一的买菜总花费是多少钱?
你的大脑会立刻算:(土豆价2 × 周一土豆量1) + (西红柿价3 × 周一西红柿量2) = 2 + 6 = 8。
矩阵乘法 A @ B 干的就是这件事——一次性把所有组合算完!
✍️ 第三关:手把手教你怎么算(口诀)
口诀:“左行固定,右列滑动,乘完加和,放进格子。”
拿上面的例子,结果是一个 3行(市场数) × 3列(天数) 的矩阵。
第1步:算“市场1 在 周一”的花费(结果第1行第1列)
- 拿出 A的第1行
[2, 3] - 拿出 B的第1列
[1, 2] - 计算:
(2×1) + (3×2) = 2 + 6 = 8
第2步:算“市场1 在 周二”的花费(结果第1行第2列)
- 拿出 A的第1行
[2, 3] - 拿出 B的第2列
[4, 1] - 计算:
(2×4) + (3×1) = 8 + 3 = 11
一直算下去,直到把 A的3行 和 B的3列 全部搭配完,得到最终结果:
| 市场\天数 | 周一 | 周二 | 周三 |
|---|---|---|---|
| 市场1 | 8 | 11 | 13 |
| 市场2 | 6 | 17 | 11 |
| 市场3 | 9 | 22 | 16 |
🚧 第四关:为什么你的 np3 @ np4 报错了?(关键!)
矩阵乘法的铁律(入场券):
左边矩阵的“列数” 必须 等于 右边矩阵的“行数”。
因为你要把左边的“行元素”和右边的“列元素”一一配对相乘,数量对不上,就没法配对!
看你之前的报错代码:
np3形状是 3行 2列。np4形状是 3行 2列。
套用铁律:
- 左边的列数是
2 - 右边的行数是
3 2 ≠ 3,配不上对! 所以电脑直接报错,拒绝计算。
那为什么加了个 .T(转置)就行了?
np4.T把表格横过来了,形状变成了 2行 3列。- 现在左边的列数是
2,右边的行数也是2。对上了! - 所以
np3 @ np4.T结果就是 3行(左边的行数) × 3列(右边的列数),得到一个 3x3 的方阵。
🧠 终极灵魂总结(给你装进脑子里)
看符号认亲妈:
- 看到
*号 → 用广播规则(对应位置相乘,小的复印)。 - 看到
@或np.dot→ 用矩阵规则(左行碰右列,乘完求和)。
- 看到
矩阵乘法只看两数:
- 写出来
(m行, n列) @ (n行, p列),中间的n必须相等! - 结果一定是 **
(m行, p列)**。
- 写出来
现实意义:
*(广播):给表格里每个格子都做相同的加减乘除(比如全场打8折)。@(矩阵):做系统性的组合变换(比如根据单价和数量算总价,或者图片旋转、神经网络计算)。
现在你再回头看看那个报错,是不是觉得特别清晰了?(3,2) 和 (3,2) 中间是 2 和 3,不相等,所以 @ 不伺候,但 * 因为广播规则能伺候(因为形状兼容)。记住:*管对应,@管组合! 👍
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LGQ的博客!