iterrows 不该用,因其返回 (index, series) 导致每次迭代都构造 series 并对齐索引,产生隐式循环和多余拷贝,性能比向量化操作慢 10–100 倍,且无法通过扩容提速。

为什么 iterrows 在大多数情况下不该用
iterrows 返回的是 (index, Series) 对,每次迭代都触发 Series 构造和索引对齐,实际是隐式循环 + 多余拷贝。哪怕数据只有几千行,它也比向量化操作慢 10–100 倍。更关键的是:一旦你写了 iterrows,后续几乎没法靠加机器资源提速——瓶颈在 Python 层,不是 I/O 或内存。
用 loc / numpy.where 替代条件赋值
常见场景:根据某列条件修改另一列值。比如把 df['score'] > 80 的行,df['level'] 设为 'A'。
❌ 错误写法(慢且易出错):
for idx, row in df.iterrows():
if row['score'] > 80:
df.loc[idx, 'level'] = 'A'
✅ 正确做法(零循环、原子操作):
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 用布尔索引直接定位:
df.loc[df['score'] > 80, 'level'] = 'A' - 需要多条件分支时,用
numpy.where:df['level'] = np.where(df['score'] >= 90, 'A', np.where(df['score'] >= 80, 'B', 'C')) - 避免链式赋值警告:始终用
.loc,不要写df[df['score'] > 80]['level'] = ...
用 apply + axis=1 的时候要当心
apply 看起来比 iterrows 高级,但 axis=1 实际仍是逐行调用 Python 函数,性能只比 iterrows 略好一点,本质没脱离解释器开销。
✅ 更优替代方案:
- 能用向量化函数就不用
apply:比如字符串操作优先用str.contains、str.split,而不是apply(lambda x: x['name'].split()[0]) - 数值计算优先用
numpy原生函数:df['dist'] = np.sqrt((df['x1'] - df['x2'])**2 + (df['y1'] - df['y2'])**2) - 真需要复杂逻辑?先提取所需列转成
numpy.ndarray,再用纯 NumPy 向量化处理,最后塞回 DataFrame
自定义函数无法向量化时的折中方案
有些逻辑确实没法一步向量化,比如调用外部 API、依赖上一行状态、或含 try/except 分支。这时别硬套 iterrows,考虑这些路径:
- 用
itertuples替代iterrows:返回命名元组,无 Series 构造开销,快 2–5 倍;访问字段用row.name而非row['name'] - 批量处理 + 缓存:把待处理 ID 提取出来,用
requests.post批量请求,而不是每行发一次 HTTP - 状态类逻辑(如累计计数重置):用
groupby().apply()或shift+ 布尔掩码构造辅助列,避免显式循环
真正卡在“必须逐行”时,itertuples 是底线;写 iterrows 前,先问自己:这个操作能不能拆成三步向量化完成?多数时候答案是能。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










