代码炼器
你以为写 for 循环就够了——逐个元素算,多直觉。可循环之魔正盘踞在你的直觉傲慢里:它不住在 for 循环里,住在你"以为 for 循环就够了"的地方。每一笔天真的代价,它都给你记着账。
炼器殿的门
殿门没有锁。推开时你闻到一股烧焦的铜味——像有什么东西在这里算了一整夜,烧穿了自己。正中悬着一块发光的石板,底座刻着一行小字:"此为炼器之台。代码即法器,算力即灵力。"贝叶斯先师递来一块玉简——上面刻着四个字:Jupyter Notebook。
「接住。在 cell 中输入 %lsmagic——这是法器的铭文。它认了主,才肯为你算。」
「for 循环……谁都写得出 for 循环。打赌吧——你押哪段用 for 写和 NumPy 差不多?押错一笔,我记一笔。」
速度之赌挑战器 · Jupyter 认主 + 反直觉下注 + 性能差距图谱
认主 %lsmagic → 三段代码剪影押注 → 计时器弹出真容 → 性能差距图谱拼合
性能差距图谱
语法试炼台 · Python 的底子
试炼台是一面巨大的石壁,上面空着无数凹槽,等着被代码填满。贝叶斯先师递来一枚刻刀:"刻对了,凹槽亮起来;刻错了,石壁会吃掉你的字。"循环之魔盘踞在石壁顶端:"从最简单的开始——求 1 到 100 万的和。你先写个 for 循环,多顺手啊。"
「对是对了。但你有没有觉得……慢了点?石碑角落会弹出计时——别怪我,怪你的写法。」
语法试炼台 · for 累加 vs 内置 sum + 5 张语法卡片
刻 for 循环求和 → 计时浮现 → 换 sum() 重写 → 点亮 5 张语法卡片
法器觉醒 · ndarray 的真名
那块刻着 import numpy as np 的石板悬浮在半空,表面流动着蓝色的光纹。你伸手触碰——光纹涌入指尖,掌心浮现一个发光的括号 []。循环之魔在暗处冷笑:"一个数组而已。你以为换个名字就能跑得更快?"
「ndarray 不是更快的列表。它是一块连续内存上的同质数据。拖动维度标尺,验证广播三规则;走通三种索引光路——它才肯醒。」
法器觉醒 · 连续内存网格 + 广播维度标尺 + 索引迷宫
对比 NumPy vs 列表推导 → 拖动维度验证广播 → 点亮布尔/花式/切片三种索引
ndarray 连续内存网格 · 整批运算可视化
广播维度标尺 · 从右向左比较
索引迷宫 · 三种取法光路
循环之刑 · 三重 for 矩阵乘
试炼台尽头是一面巨幅石壁,上面浮着两个 1000×1000 的矩阵——密密麻麻的数字,像两片数字的汪洋。循环之魔从暗影里完全显形:一个由无数 for 关键字缠绕而成的巨人,每一个 for 都是一根肋骨。"来吧,用你最拿手的三重 for 循环,把这两个矩阵乘出来。"
「一个一个算,多直观。你感觉到了吗?每一个 for 都在替你数数——10 亿次迭代,我替你数。」
「写。然后看时间。再用法器——np.dot,一行。」
循环之刑 · 三重 for 进度爬行 + 向量化光束 + 1500x 差距柱状图
执行三重 for 看龟速爬行 → 换 np.dot 光束贯穿 → 差距具现柱状图
三重 for 循环矩阵乘 · 1000×1000
线性代数殿 · 矩阵的心脏
穹顶大厅里悬浮着无数矩阵——有的方正端庄,有的边缘在颤抖。贝叶斯先师指着石壁上的方程组 Ax=b:"三百年前人类用手算这个。现在你用一行代码。但一行写错了,比手算还糟。"循环之魔从穹顶传来:"先求逆再乘——多直觉啊,教科书第一页就教了。"
「拖动条件数滑块,亲手看 inv 在病态矩阵上的误差比 solve 大多少。inv 把条件数平方放大——solve 用 LU 分解从不显式构造 A⁻¹。」
线性代数殿 · inv/solve/lstsq/SVD + 条件数滑块 + 矩阵形态
四种解法切换 → 拖动条件数看误差 → 点亮 4 种矩阵形态
数据炼洗池 · DataFrame
穹顶落下的卷轴在你面前展开——有的缺了半行,有的涂改得面目全非,有的字迹根本不属于这张纸。贝叶斯先师递来第二把法器:一枚刻着 import pandas as pd 的玉牌。"这叫 DataFrame,能把混乱的数据变成秩序。但前提是——你用对了方法。"循环之魔从池边探出头:"一行一行洗嘛,用 apply 逐行处理,多清楚。"
「一行一行来,多稳。功能正确就行——慢点怕什么?账,我继续记。」
数据炼洗池 · 脏数据可视化 + apply vs 向量化计时
看缺失/重复/类型错/异常 → 逐行 apply 120ms → 向量化 2ms → Pandas 觉醒
精度深渊 · 0.1+0.2≠0.3
池水退去,地面裂开一道缝。你往下看——没有底。缝隙里飘出低沉的嗡鸣,像无数个数字在同时报错。贝叶斯先师蹲下身,在裂缝边缘写下:0.1 + 0.2。"你猜,等于几?"循环之魔冷笑:"0.3 呗,幼儿园就会了。"缝隙深处的嗡鸣忽然清晰了一瞬——那不是数字,是一个声音:"64 位装不下无穷。"
「写 softmax 不减最大值会溢出成 nan。减去最大值——这是数值稳定的救赎。逐一验证五种陷阱。」
精度深渊 · 52 位尾数可视化 + softmax 稳定化 + 陷阱清单
验证 0.1+0.2 → 看 52 位尾数截断 → softmax 溢出成 nan → 减最大值稳定
0.1 + 0.2 = ? · IEEE 754 double
数值稳定性陷阱清单 · 五种
可视化之镜 · 照见真容
深渊合拢处升起一面巨大的铜镜,镜面暗淡无光。贝叶斯先师递来一支光笔:"把你的数据画上去。数字会骗你,图形不会。"循环之魔缩在角落,第一次沉默了——它怕镜子。你在镜面上画下第一笔——镜面亮了,数字变成了形状。
「拖动数据量滑块,看 for 曲线和向量化曲线在 10⁴ 处分叉、10⁶ 处差距拉到 100 倍。图形是数值计算的诊断器。」
可视化之镜 · 性能曲线 + 误差箱线图 + 缺失值热力图
画 for vs 向量化曲线 → 误差箱线图 → 缺失值热力图
for vs 向量化 · 耗时曲线(拖动数据量)
inv vs solve · 相对误差箱线图
缺失值热力图 · 清洗前后
预处理工坊 · 起跑线
铜镜之后是一间锻造工坊,墙上挂着各种量具——有的刻度均匀,有的只有 0 和 1。贝叶斯先师拿起一把量具:"你的数据,年龄从 0 到 100,收入从 0 到 100 万。把它们丢进同一个模型——收入会碾碎年龄。"循环之魔靠在门框上:"那就一个一个标准化嘛,逐列算。"先师没理它,只看你:"用向量化。但注意顺序——先划分,还是先标准化?"
「先标准化再划分,多省事——一次 fit 全部数据。验证集不也在里面嘛,有什么关系?」
预处理工坊 · Scaler/编码 + 数据泄露可视化 + K-fold
切 StandardScaler/MinMaxScaler/OneHot → 切换划分顺序看泄露 → K-fold 5 折
数据泄露陷阱 · 划分顺序决定一切
K-fold 交叉验证 · 5 折轮流验证
梯度之门 · autograd 与工具链
金光中浮现第三把法器——一枚刻着 import torch 的玉牌,表面流动着前向和反向的光流。贝叶斯先师在空中画了一个函数:y = (x²).sum()。"你手算 dy/dx 要多久?让法器自己算。"循环之魔嗤笑:"求导嘛,一个一个来——"先师没等它说完,把玉牌递给你。
「前向建图,反向求导。点前向看蓝色光流,点反向看金色光流沿链式法则回溯。再把张量移到 GPU——成百上千条光线同时走。」
梯度之门 · 计算图 + 三大 ML 库 + GPU 并行
构建计算图 → 前向/反向光流 → 点亮三大 ML 库 → GPU 并行对比
计算图 · y=(x²).sum() · 前向蓝 / 反向金
CPU 串行 vs GPU 并行 · 大矩阵乘
Boss 战 · 循环之魔三问
殿门尽头是一片虚空。循环之魔盘踞在虚空中,身形比之前庞大十倍——无数 for 关键字编织成它的鳞片,每一片都在缓慢转动,发出齿轮咬合的噪音。它身后是一面巨大的石碑,上面空空如也。"你以为学会了向量化就能赢我?回答三个问题。答对一个,我退一步;答错一个——你的法器碎一把。"石碑上开始浮现字迹——你这一路刻下的每一道排除刻痕,正在一一亮起。
「三问。第一问翻循环账,第二问追本质,第三问——用你刻下的六道刻痕收网。你以为 for 循环是错的?最后我问你:什么时候 for 反而比向量化好?」
循环债累计 0 笔 · 三问全对后清零