You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars:高效获取第二大元素或小n值下的第n大元素

Polars:高效获取第二大元素或小n值下的第n大元素

嘿,这个问题问到点子上了!在Polars里处理这类「取第n大元素(尤其是n远小于列的总规模)」的需求,完全没必要给整个列做全量排序——那样太浪费资源了,咱有更高效的玩法,我给你拆解清楚:

核心高效方法:top_k()

当n很小的时候,top_k(n)绝对是首选!它的原理是维护一个大小为n的堆,只找出列中最大的n个元素,时间复杂度是O(m)(m是列的行数),比全排序的O(m log m)高效太多,特别适合n远小于m的场景。

举个实际的例子,先创建一个测试DataFrame:

import polars as pl

# 构造包含重复值的测试数据
df = pl.DataFrame({"values": [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]})

获取第二大元素

我们只需要取最大的2个元素,然后取其中的第二个(也就是第二大的那个):

second_largest = df.select(pl.col("values").top_k(2).nth(1)).item()
print(second_largest)  # 输出:6

这里top_k(2)会返回降序排列的前2大元素[9,6],用nth(1)就能拿到第二大的元素;如果你习惯用last()也可以,效果是一样的。

通用获取第n大元素

把逻辑推广到任意小n的情况,只需要把top_k的参数设为n,再取索引n-1的元素就行:

n = 3
third_largest = df.select(pl.col("values").top_k(n).nth(n-1)).item()
print(third_largest)  # 输出:5

去重后的第n大元素

如果你的需求是去重后的第n大元素,只需要在top_k前加个unique()就行:

# 去重后的第二大元素
second_largest_unique = df.select(pl.col("values").unique().top_k(2).nth(1)).item()
print(second_largest_unique)  # 输出:5

避坑提醒:别用全量排序

可能有人会想到先排序再取第n个元素,比如pl.col("values").sort(reverse=True).nth(1)——这种方法在n很小的时候完全没必要,全量排序会对整个列做排序操作,数据量一大性能差距就会很明显,所以优先用top_k就对了!

备注:内容来源于stack exchange,提问作者Test

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 12:39:37