发布于2026-07-18 阅读(0)
扫一扫,手机访问
在数据分析或日常脚本里,取某列数值最大的前 N 行是高频操作。很多人第一反应是 sort_values 加 head,但 nlargest 其实才是更优解,尤其在数据量大的时候,效率差距不是一星半点。

核心在于算法的底层选择。nlargest 内部基于堆(heap)实现,时间复杂度是 O(n log k),而 sort_values 是全表排序,复杂度 O(n log n)。当 N 远小于数据行数时,跳过全量排序带来的提速非常直接——百万级数据上,差距可能从秒级变成毫秒级。
不过有个前提:nlargest 只支持数值列(int/float),如果对字符串或 datetime 列直接调用,会报 TypeError。想按时间取最新?那就得先把列转成 datetime64 类型。
调用形式很简单:df.nlargest(n, columns, keep='first')。三个参数里:
n:要取的行数,必须是正整数,这个不用多说。columns:可以传单列名(比如 'score'),也可以传列名列表(比如 ['score', 'age']);多列时按顺序优先级排序,效果相当于 sort_values(['score', 'age'], ascending=[False, False])。keep:控制重复值处理——'first'(默认,保留首次出现)、'last'、'all'。注意 'all' 会返回所有并列第 N 名的行,结果可能超过 N 行。举个例子:df.nlargest(5, 'price', keep='all') 会返回所有 price 并列第 5 名的行,结果可能 >5 行。这在处理排名并列场景时很实用。
实际使用中,下面几个坑踩的人不少:
NaN:默认情况下 NaN 会被排在最后,nlargest 仍然会返回前 N 行(包含 NaN 行),但这通常不是我们想要的——建议先 dropna(subset=['col']) 清洗一下。object 但实际存的是数字字符串(比如 '123'):直接调用会报错或返回空,必须先用 pd.to_numeric(df['col'], errors='coerce') 转成数值类型。nlargest 返回的新 DataFrame 索引默认保留原始索引,不是 0,1,2… 的连续序列。如果需要重置,可以链式调用 .reset_index(drop=True)。也不是所有场景都适合用 nlargest。当 N 接近总行数(比如取前 90%)时,堆操作的开销反而可能高于直接排序,这时候 df.sort_values('x', ascending=False).head(n) 更稳妥。
另外,如果后续还要按其他字段二次分组或聚合,用 sort_values 后接 groupby().head() 更自然。nlargest 本身不支持分组内 top-N,虽然可以通过 groupby().apply(lambda x: x.nlargest(n, 'col')) 实现,但性能较差,不推荐。
总结一下,真正省心又高效的前提是:单列、纯数值、N 远小于数据行数、且不需要分组上下文。满足这些条件,nlargest 就是最优解。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8