成列
numpy、pandas、matplotlib、seaborn、scikit-learn——五个库,五套 API,五份文档。但它们底下是同一条列:一块连续的字节,被贴上名字,被接到眼睛上,被压成一个矩形。
这本书不教 API(那些都能查)。它讲的是每一层要什么形状,以及形状不对时它怎么表示——因为五层里只有一层会真的拦住你,其余四层出了问题都是安静的。
这五个库共用的东西不是「Python」,是一条列。
numpy 说它是一块连续内存加一张说明书;pandas 给它贴上名字,于是有了对齐;seaborn 要它站成长表,才能映到视觉通道上;sklearn 要它压成一个纯数字的矩形。同一条列,四层意思。
而学这套工具真正难的地方从来不是记住函数名,是知道每一次交接会静默地改变什么——行数变多了、方向反了、名字对不上了、测试集泄漏了。这本书就是那份交接单。
为什么值得读
三个从书里挑出来的数字,都是本机跑出来的:
| 它看起来是 | 它其实是 | 章 |
|---|---|---|
| 一份完全没有信号的随机数据,交叉验证报出 98.9% 的准确率 | 挑特征这一步写在了交叉验证外面。放进 Pipeline 之后:51.1%(真值 50%) | 18 |
| 五个客户的表和订单表一合并,客户平均年龄从 40.00 变成 29.09 | 一号客户下了 7 单,他的年龄被复制了 7 份。行数从 5 变成 11,没有任何提示 | 10 |
| 一个方阵做「行归一化」,四行的和是 0.8、2.0、0.85、1.25 | 广播从右往左对齐,所以做的是列归一化。长方形矩阵上会报错,方阵不会 | 3 |
这三件事的共同点:代码没有一行是错的,也没有任何东西报错。数据还在,程序跑通了,结果看起来完全正常——只是它在回答另一个问题。
目录
一条列
COLUMNnumpy。底下永远是一条平的列,其余全是说明书——shape 怎么折、strides 每步跳多远、dtype 每格几个字节。
- 01一列数字,为什么比一列对象快几十倍34.3 MB 对 7.6 MB,23.2 毫秒对 0.4 毫秒。而在数组上写循环比在 list 上还慢 2.9 倍★ 跨领域对照表
- 02shape 只是折叠方式转置一个 122 MB 的矩阵只要 63 纳秒,比真复制快 56 万倍——但零拷贝不等于零成本★ 转置 63 纳秒
- 03axis 不是行和列,是哪根轴被吃掉「按行还是按列」两个答案都是错的。而这个误解在方阵上不会报错★★ 方阵上不报错
- 04广播省掉的循环,和它悄悄给你的 (n, n)规则只有三行。一个 (10000, 1) 加一个 (10000,),76 KB 变成 0.75 GB★★ 76 KB → 0.75 GB
- 05改这个,那个会不会跟着变切片和花式索引打印出来一模一样,一个共用内存一个不共用。还有:10 个元素扣住 381 MB★ 切片是视图
贴上名字
NAMEpandas。给每一列贴上名字,于是有了对齐——也有了这一卷全部的麻烦。这一卷讲的全是「静默地变多」和「静默地变少」。
- 06你以为在加两列数,其实先做了一次 join两个各三个数的 Series 相加,结果四行,两个是 NaN。而 .to_numpy() 是把这套保护关掉的开关★★ 4 个数只剩 2 个
- 07四把刀:[ ]、.loc、.iloc、布尔同一个冒号,.loc 含右端 .iloc 不含。外加 pandas 3 刚换掉的那套复制规则★ pandas 3 的新规矩
- 08缺失值不是零,每种填法都是一个假设每列只缺 5%,十列 dropna 丢掉 39.3% 的行。均值填充让相关系数掉 16.0%★★ 相关系数掉 16%
- 09groupby 是拆开、各算各的、再拼回去比手写字典循环快 11.0 倍;而 .apply 只快 25%。分组键是 NaN 的行被静默丢掉★ 两行悄悄没了
- 10merge 会静默地放大你的行数5 行变 11 行,平均年龄 40.00 变 29.09。一个几乎没人写的参数能当场拦住它★★ 平均年龄 40 变 29
接到眼睛上
SEEmatplotlib 和 seaborn。画图不是画画,是把列接到视觉通道上——而在碰任何画图函数之前,得先把数据摆成对的形状。
- 11一次 melt,决定你能不能一句话画出图同样 12 个数,一张把「城市」藏在列名里,一张把它变成一列。加一个城市,一边改代码一边不用改★ 宽表 4×4 → 长表 12×3
- 12两套 API:状态机是 REPL 的遗产连着 plt.figure() 两次再 plt.plot(),线画在了第二张图上。这不是 bug,是 1990 年代的设计★ 画到别人身上
- 13一切都是 Artist,所以一切都能改一张最简单的折线图里有 11 个对象,一条线有 49 个属性。两行代码取代大部分「怎么改 XXX」的搜索★ 11 个孩子
- 14seaborn 不是美化,是图形语法同一张分面图,10 行 418 字符对 2 行 95 字符。加一个维度,一边重写一边改一个词★★ 10 行变 2 行
- 15默认设置里藏着的那些谎y 轴从 97.9 起,1.03 倍的差别看起来是 31 倍。Anscombe 四组统计量全同。十万个点里 46.2% 看不见★★ 放大 30 倍
唯一的队形
FITscikit-learn。208 个模型只认一种形状、只会三个动词。这是全书唯一会替你把关的一层——但它把关的只有形状,不包括「你的评估流程有没有被污染」。
- 16三个动词:fit、transform、predict208 个估计器,同一套接口。换模型就是换一行 import——而最重要的设计是把 fit 和 transform 拆开★ 换模型只换一行
- 17把世界压成一个矩形一列城市名变四列 0 和 1,五千段文本变 4000 列(98.4% 是零)。以及上线第一天就会遇到的那个问题★ 1 列变 4000 列
- 18一份纯随机的数据,我让它给出 98.9%50 个样本、5000 列噪声、标签抛硬币。放进 Pipeline 之后掉回 51.1%。唯一的差别是挑特征在里面还是外面★★★ 全书招牌
- 19一个分数是没有意义的只换随机种子跑 200 次:93.57% 到 100.00%。这比五个不同模型之间的差距还大★★ 93.57 到 100.00
- 20分数也会骗人一个什么都不做的模型准确率 98.58%。随机森林说最重要的那列是纯噪声,两根噪声拿走 75.4%★★ 噪声拿走 75.4%
合上书之后
AFTER这条列往下还要走多远,以及怎么把五层重新接回一条线。
写给谁
这本书写给
- 会写代码、但数据这套工具是拼凑着学的人。能跑通教程,遇到形状报错就开始试——试到不报错为止,但不知道刚才发生了什么。
- 用过 pandas 但被 index 咬过的人。见过莫名其妙的
NaN、见过SettingWithCopyWarning、见过合并之后行数变多。 - 想搞清楚「为什么我的模型分数这么好」的人。卷 IV 那四章可能是这本书最贵的部分。
- 做别的方向、想知道这一套在干什么的工程师。第 1 章那张跨领域对照表就是为你写的——这套东西和 SQL、GPU、列式数据库、响应式流是同一个想法的不同实现。
这本书不打算做的
- 不是 API 手册。函数签名和参数列表官方文档写得更好,也更新得更快。这里讲的是「为什么是这个形状」。
- 不讲机器学习算法本身。卷 IV 讲的是评估流程和数据泄漏,不讲随机森林怎么分裂、SVM 的核函数怎么选。
- 不装环境。每章的「⌨ 自己跑一遍」给的是能直接粘的代码和已经跑出来的答案。想在浏览器里跑就用 jupyter.org/try-jupyter,numpy 和 pandas 都是现成的。
- 不假装数字是通用的。耗时类的数字取决于机器,但相对关系是稳的;非耗时的数字在同版本下应该逐位复现。
怎么读
- 按顺序读。后面的每一章都在用前面的结论:第 3 章的
keepdims要靠第 4 章的广播规则才讲得通,第 7 章的写时复制是第 5 章视图与副本的续集,第 18 章的泄漏是第 16 章那个 fit/transform 拆分的反面。 - 只有一个小时的话,读第 18 章。那二十行代码是这本书最值得亲手跑的东西。
- 每章末尾有一张「⌗ 交接单」——这一章的数据进来是什么形状、出去是什么形状、谁在检查。第 23 章把 23 张收成了一张表。
- 每章有一个「✗ 这个直觉是错的」。它们大多是我自己踩过、或者见别人踩过的。
- 键盘 ← / → 翻页,右上角按钮开目录,Esc 关闭。