第4章 · 索引切片的代价课 本章要回答的三个问题:为什么基本切片改的是原数组?花式索引和布尔掩码为什么慢、又为什么安全?用 for 循环遍历数组到底错在哪,什么时候该用 nditer? 为什么会有这一章 第 2 章画下视图与拷贝的分界线,本章是这条线最密集的应用现场。索引与切片是每天要写几十次的操作,也是内存行为差异最大的一族:a[1:5] 纳秒完成共享,a[[1,3]] 逐元素搬运。不理解这一点的人,会一边惊讶"改切片动了原数组",一边困惑"按行循环怎么这么慢"。把三节的原理吃透,索引将从"背语法"变成"做预算"。
本章要回答的三个问题:为什么基本切片改的是原数组?花式索引和布尔掩码为什么慢、又为什么安全?用 for 循环遍历数组到底错在哪,什么时候该用 nditer?
第 2 章画下视图与拷贝的分界线,本章是这条线最密集的应用现场。索引与切片是每天要写几十次的操作,也是内存行为差异最大的一族:a[1:5] 纳秒完成共享,a[[1,3]] 逐元素搬运。不理解这一点的人,会一边惊讶"改切片动了原数组",一边困惑"按行循环怎么这么慢"。把三节的原理吃透,索引将从"背语法"变成"做预算"。
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 4.1 基本切片为何总是视图 | 切片机制 | 步长改写示意图 + 切片赋值演练 |
| 4.2 花式索引与布尔掩码的拷贝陷阱 | 高级索引机制 | 视图/拷贝对照实验 + 掩码改写套路 |
| 4.3 迭代为什么慢与nditer | 循环的代价 | 三种遍历计时 + 外部循环模式 |
问:切片和花式索引长得差不多,怎么一眼区分?
答:方括号里是冒号、数字与冒号的组合,就是基本切片(视图);方括号里是列表、数组或布尔条件,就是高级索引(拷贝)。一句话:冒号给视图,下标数组给拷贝。
问:既然切片是视图有风险,为什么不全部设计成拷贝?
答:拷贝的代价同样惊人——每次切片都复制整块的话,转置一个 1GB 矩阵就要 1GB 新内存。视图是性能核心设计,风险靠纪律管理:知道分界线,风险就变成了便利。
问:nditer 名字吓人,很难学吧?
答:核心就两个参数——external_loop 拿块、readwrite 写回,加上一条"写回用省略号"的纪律。十分钟上手,换来的循环加速常在十倍以上。
索引解决"取哪一块",形状操作解决"取出来怎么摆"。第 5 章的 reshape、转置、展平,全是零拷贝家族的成员——届时你会回头感谢本章练出的判断力。附带一句学习建议:本章三节各带一个可复现实验,做完实验再看要点回顾,记忆留存率远高于纯阅读。