Polars 中按组筛选匹配项并提取最高分对应值的完整指南
技术百科
聖光之護
发布时间:2026-01-25
浏览: 次 本文详解如何在 polars 中对分组数据进行条件匹配(如 seq_grp == match)并精准提取每组内满足条件的最高分记录;同时支持反向需求——提取不匹配项中的最高分及其关联字段。
在 Polars 数据处理中,常需基于分组(group_by)执行「条件筛选 + 值提取」操作,例如:对每个 seq 分组,找出 match 列中与 seq_grp 相等的行,并返回该组中对应 score 最大的那条完整记录;或反过来,提取 match ≠ seq_grp 时得分最高的非匹配项及其 match 值。这类任务不能仅靠简单过滤或 .list.get() 实现,而需结合布尔索引、聚合函数与向量化索引(如 .arg_max())。
以下以原始数据为例,逐步实现两类核心场景:
import polars as pl
df = pl.DataFrame({
"seq": "foo bar bar duk duk baz baz baz zed".split(),
"seq_grp": "aa bb bb dd dd cc cc cc zz".split(),
"match": "aa cc bb dd dd ff cc cc yy".split(),
"score": [10, 8, 20, 8, 7, 5, 6, 4, 6],
})✅ 场景一:提取每组中 seq_grp == match 的最高分记录
这是最常见需求——保留“匹配成功”且得分最优的样本。推荐使用 惰性计算链式操作,避免中间 list 膨胀:
result_match = (
df.lazy()

.filter(pl.col("seq_grp") == pl.col("match")) # 先筛选匹配行
.group_by("seq", maintain_order=True)
.agg(
pl.col("seq_grp").first(), # 每组 seq_grp 唯一,取其一
best_match=pl.col("match").first(), # 同上(可省略,因已过滤)
top_score=pl.max("score"),
# 若需原始行全部字段,可用 struct + arg_max(见下文进阶)
)
.collect()
)输出:
shape: (4, 4) ┌─────┬─────────┬────────────┬───────────┐ │ seq ┆ seq_grp ┆ best_match ┆ top_score │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str ┆ i64 │ ╞═════╪═════════╪════════════╪═══════════╡ │ foo ┆ aa ┆ aa ┆ 10 │ │ bar ┆ bb ┆ bb ┆ 20 │ │ duk ┆ dd ┆ dd ┆ 8 │ │ baz ┆ cc ┆ cc ┆ 6 │ └─────┴─────────┴────────────┴───────────┘
? 提示:若需返回整行原始数据(而非仅聚合字段),可改用 struct 构造后索引:df.lazy().filter(pl.col("seq_grp") == pl.col("match")).with_columns( row_id = pl.int_range(0, pl.count()) ).group_by("seq", maintain_order=True).agg( pl.col("row_id").get(pl.col("score").arg_max()).alias("best_idx") ).join( df.lazy().with_columns(row_id = pl.int_range(0, pl.count())), on="row_id", how="left" ).select(df.columns).collect()
✅ 场景二:提取每组中 seq_grp != match 的最高分记录(含对应 match 值)
这正是问题中强调的「top scoring non-cc match」需求。关键在于:不能先 group_by 再判断,而应在过滤后分组,再用 .arg_max() 定位索引并 .get() 提取对应 match:
result_non_match = (
df.lazy()
.filter(pl.col("match") != pl.col("seq_grp")) # 排除自匹配
.group_by(["seq", "seq_grp"], maintain_order=True) # 注意:保留 seq_grp 便于对齐
.agg(
best_non_match=pl.col("match").get(pl.col("score").arg_max()),
top_score=pl.max("score"),
)
.collect()
)输出:
shape: (3, 4) ┌─────┬─────────┬────────────────┬───────────┐ │ seq ┆ seq_grp ┆ best_non_match ┆ top_score │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str ┆ i64 │ ╞═════╪═════════╪════════════════╪═══════════╡ │ bar ┆ bb ┆ cc ┆ 8 │ │ baz ┆ cc ┆ ff ┆ 5 │ │ zed ┆ zz ┆ yy ┆ 6 │ └─────┴─────────┴────────────────┴───────────┘
✅ 此结果精确对应问题中期望的 baz/cc → ff/5 行。
⚠️ 注意事项与最佳实践
- 避免 .list.get(0) 类中间结构:group_by(...).agg(...) 生成 list 列后用 .list.get() 易出错且低效;优先用 filter → group_by → agg 流水线。
- arg_max() 是关键:它返回最大值索引(int),配合 .get() 可跨列安全提取关联字段,比 .first() 或 .max() 更精准。
- maintain_order=True 必须显式声明:确保分组后顺序与原始一致,尤其在依赖位置逻辑时。
- 惰性执行(.lazy())强烈推荐:复杂链式操作中可自动优化执行计划,提升性能并减少内存峰值。
通过以上方法,你不仅能复现 FRAME_3 的匹配最优解,还能灵活拓展至任意条件下的组内 Top-K 提取,真正掌握 Polars 高效分组分析的核心范式。
# ai
# 这是
# 链式
# 还能
# 进阶
# 推荐使用
# 若需
# 最优
# int
# Struct
# 组中
# Filter
# 原始数据
# 聚合函数
# yy
# 每组
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么关闭自动维护 Win11禁用系统自动
- Flask 表单数据通过 SMTP 发送邮件的完整
- Win11声音忽大忽小怎么办 Win11音频增强功
- Win11怎么关闭自动调节亮度_Windows11
- c++的位运算怎么用 与、或、异或、移位操作详解【
- Win11怎样安装微信开发者工具_Win11安装开
- c++如何实现一个高性能的环形队列(Ring Bu
- 如何在Golang中处理通道发送接收错误_防止阻塞
- Win11无法识别耳机怎么办_解决Win11插耳机
- windows 10应用商店区域怎么改_windo
- Python音视频处理高级项目教程_FFmpegP
- Python对象比较排序规则_集合使用说明【指导】
- Win11怎么开启游戏模式_Win11优化游戏帧数
- Win11如何更新显卡驱动 Win11检查和安装设
- 如何在Golang中实现微服务服务拆分_Golan
- PythonFastAPI项目实战教程_API接口
- 如何使用Golang log设置日志输出格式_Go
- Win11怎么开启剪贴板历史记录_Windows1
- Windows11怎样开启游戏模式_Windows
- Win10怎样安装PPT模板_Win10安装PPT
- Windows怎样关闭开始菜单广告_Windows
- Windows10系统怎么查看设备管理器_Win1
- Win11怎么调整屏幕亮度_Windows 11调
- Go语言中CookieJar的持久化机制解析:内存
- Win10怎么限制单程序CPU占用上限_Win10
- C++如何编写函数模板?(泛型编程入门)
- Mac怎么开启“任何来源”_Mac安装未签名应用的
- php命令行怎么运行_通过CLI模式执行PHP脚本
- php转mp4怎么设置帧率_调整php生成mp4视
- php下载安装后swoole扩展怎么安装_异步框架
- Win11怎么设置任务栏大小_Windows11注
- Win11怎么关闭触摸屏_禁用Win11笔记本触摸
- PHP的Workerman对架构扩展有啥帮助_应用
- Python高性能计算项目教程_NumPyCyth
- Mac怎么进行语音输入_Mac听写功能设置与使用【
- Python包结构设计_大型项目组织解析【指导】
- Win11怎么关闭右下角弹窗_Win11拦截系统通
- Win11如何更改任务栏颜色 Win11自定义任务
- 本地php环境出现502错误_nginx或apac
- Win11截图快捷键是什么_Win11自带截图工具
- php本地部署后session无法保存_sessi
- Windows10如何查看蓝屏日志_Win10使用
- Win11如何设置系统语言_Win11系统语言切换
- php8.4新语法match怎么用_php8.4m
- c++中如何求一个数的平方根_c++ sqrt函数
- Win11怎么查看激活状态_查询Windows 1
- Win11怎么开启空间音效_Windows11耳机
- c++中的Tag Dispatching是什么_c
- c++20的std::format怎么用 比pri
- Win10怎样卸载iTunes_Win10卸载iT


QQ客服