第6章 · 运算广播与ufunc 本章要回答的三个问题:两个数组做运算,内存账本上记了几笔?形状不同的数组为什么能直接相加,广播规则到底怎么执行?ufunc 是什么,out 参数和原地运算能省下多少? 为什么会有这一章 运算是 NumPy 存在的理由,但多数教程只教"加号怎么用"。内存视角下的运算有清晰的账本结构:读两个输入块、写一个输出块,每笔都真金白银。理解账本之后,广播不再是"神奇的对齐"而是一套可执行的形状规则;ufunc 的 out 参数也不再是冷门参数,而是消灭中间数组、把内存占用砍到三分之一的实用工具。
本章要回答的三个问题:两个数组做运算,内存账本上记了几笔?形状不同的数组为什么能直接相加,广播规则到底怎么执行?ufunc 是什么,out 参数和原地运算能省下多少?
运算是 NumPy 存在的理由,但多数教程只教"加号怎么用"。内存视角下的运算有清晰的账本结构:读两个输入块、写一个输出块,每笔都真金白银。理解账本之后,广播不再是"神奇的对齐"而是一套可执行的形状规则;ufunc 的 out 参数也不再是冷门参数,而是消灭中间数组、把内存占用砍到三分之一的实用工具。
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 6.1 元素级运算的内存账本 | 运算花几块内存 | 三笔账模型 + 临时数组优化 |
| 6.2 广播规则的形状对齐 | 形状不同为何能算 | 四步对齐法 + 三维实例推演 |
| 6.3 ufunc的out参数与原地运算 | 怎么少分配 | out 用法与溢出陷阱 |
本章三节环环相扣:先会记账,才能看懂广播替你省掉的中间块;会用广播,才能理解 out 参数在完整管线里的位置。建议按序通读,不要跳。
问:广播规则总是记不住,有诀窍吗?
答:别背结论,走流程。四步对齐法每次手工推一遍,推十几遍就内化了。真正要背的只有一句:右对齐、缺维补一、有 1 可扩、其余必须相等。
问:内存账本在什么规模的代码里才值得关心?
答:经验线是"数组超过一百万元素"。小于这个量级临时数组无感;超过之后,每次链式表达式的临时块都是几十上百 MB,账本从理论变成生存技能。
问:原地运算看起来处处更省,为什么不全部用原地?
答:原地销毁原值。调试时想对比中间结果、算法需要回溯历史值、或者原数据还要复用——这些场合原地写入都是灾难。省内存永远排在正确性之后。
运算之后要归纳总结。第 7 章的聚合(沿轴压缩)与线性代数(矩阵乘),是本章元素级运算在两个方向上的延伸:一个做减法(降维),一个做组合(乘加)。本章是全书篇幅最重的一章,三节各有实验,读完回到本页把开篇三问再答一遍,才算过关。