groupby().head(n)最快获取每组原始顺序前n行,不排序、不重排索引;需排序再取前n条时须显式sort_values()后调用head()。

用 groupby().head() 最快拿到每组前N行
直接调用 head(n) 是最简洁、性能也最好的方式。它在分组后对每个子 DataFrame 取前 n 行,底层不排序、不索引重排,纯按原始顺序截断。
常见错误是误用 nlargest() 或先 sort_values() 再 head()——除非你明确需要“最大值的前N条”,否则多此一举,还拖慢速度、改变原始顺序。
-
df.groupby('category').head(3):按category分组,每组取原始顺序前3行 - 如果某组不足3行,就返回全部(不会报错或补空)
- 结果 DataFrame 保留原始索引,不重置;如需连续索引,结尾加
.reset_index(drop=True)
想按某列排序后再取前N条?必须显式 sort_values()
head() 不排序,所以“每组最高分的前2人”这类需求,得自己先排好序。注意排序方向和稳定性:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 先
sort_values(['group_col', 'score'], ascending=[True, False]),再groupby('group_col').head(2) - 避免只对单列排序后分组——比如先
sort_values('score')再groupby('group_col').head(2),这会打乱组内原始结构,结果不可控 - 若存在相同
score,建议加kind='stable'或补充次要排序键(如'id'),保证结果可复现
nlargest() 和 apply(lambda x: x.nlargest(n, ...)) 的适用边界
nlargest() 适合“每组取数值列最大的N条”,但有隐含成本:它内部强制排序,且不支持多列联合排序(比如“先按 score 降序,再按 time 升序”就得退回到 sort_values + head)。
-
df.groupby('team')['points'].nlargest(3)返回的是Series,索引是双层(team, 原始索引),需.reset_index()才能还原成普通 DataFrame -
df.groupby('team').apply(lambda x: x.nlargest(3, 'points'))更灵活,但apply开销大,数据量大时明显变慢 - 当 N=1 且只需单列最大值时,
groupby().max()比nlargest(1)快得多
小心 head() 在重复索引或未排序数据上的行为
如果原始 DataFrame 索引有重复(比如从多个文件 concat 未 ignore_index=True),groupby().head() 仍能正常工作,但后续做 merge 或 loc 时容易出错——因为返回的索引可能不唯一。
- 检查是否有重复索引:
df.index.duplicated().any() - 保险做法:分组前先确保索引干净,或在
head()后立即reset_index(drop=True) - 另一个坑:如果分组依据列含
NaN,Pandas 默认把所有NaN归为同一组(不是忽略),需提前用dropna(subset=['group_col'])处理
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










