head和tail是pandas中安全取前n行与后n行的首选方法,n超限时返回全部行且不报错;它们仅接受整数位置参数n,不支持负数排除语义,链式中惰性执行,groupby后行为特殊。

head 和 tail 是 Pandas 中最直接、最安全的取前 N 行与后 N 行的方式。只要 DataFrame 不为空,它们就一定返回 DataFrame(哪怕 N 超出实际行数),不会报错或意外截断索引。
为什么不用 iloc[:N] 或 iloc[-N:]?
看似等价,但有关键差异:
-
head(N)在N > len(df)时返回全部行,而iloc[:N]虽然也安全,但语义上是“切片”,容易让人误以为会抛IndexError(其实不会) -
tail(N)自动处理负索引逻辑:比如df.tail(1)等价于df.iloc[-1:],不是df.iloc[-1](后者返回 Series) -
iloc[-N:]在N == 0时返回空 DataFrame,tail(0)同样如此;但tail(-1)会报ValueError,这点和iloc一致,需注意
head 与 tail 的参数陷阱
两个函数都只接受一个位置参数 n(整数),不支持传入字符串或布尔条件:
-
n为正数:取前/后n行(默认n=5) -
n为 0:返回空 DataFrame(df.head(0)→Empty DataFrame) -
n为负数:报ValueError: number of rows must be >= 0—— 它们不支持“排除前 N 行”这类语义 - 不能写成
df.head(n=10)(虽然语法合法,但属于冗余关键字调用,Pandas 源码中该参数仅定义为位置参数)
性能与链式操作中的行为
在管道(pipe)或方法链中,head/tail 是惰性的、无副作用的视图操作:
- 它们不修改原
df,也不触发copy(底层仍共享数据块,除非后续修改) - 对超大 DataFrame(千万级行),
head(10)几乎瞬时完成,因为不涉及实际数据搬运,只调整视图指针 - 但
tail(10)在某些存储格式(如未按索引排序的 Parquet)下可能略慢,因需定位末尾物理位置;不过对内存中已加载的 DataFrame,影响可忽略 - 若在链式中多次调用(如
df.sort_values(...).tail(5).head(3)),注意顺序:先tail再head才能拿到“最后 5 行里的前 3 行”
替代方案的适用边界
当 head/tail 不够用时,才考虑其他方式:
- 需要“排除前 N 行” → 用
df.iloc[N:],不是df.tail(-N)(后者非法) - 需要按条件取“最后满足某条件的 N 行” → 先布尔索引再
tail,例如df[df['x'] > 0].tail(3) - 需要保留原始索引连续性(比如做分页展示)→
head/tail会保留原索引,无需额外处理;但若用了reset_index(),就得自己控制drop=True/False - 读取 CSV 时就只取前 N 行 → 应优先用
pd.read_csv(..., nrows=N),比read_csv(...).head(N)节省内存
真正容易被忽略的是:当 DataFrame 经过 groupby、resample 等操作后返回 GroupBy 或 Resampler 对象时,head 和 tail 依然可用,但行为不同——比如 df.groupby('key').head(2) 是“每组取前 2 行”,不是“整个结果取前 2 行”。这个语义重载不看文档很容易踩空。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











