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

Polars如何原生实现列表列中指定字符串的先后顺序判断

Polars 纯原生实现列表元素先后顺序校验

你不需要借助map_elements跳出原生执行链路,Polars 原生表达式完全支持这类索引比较需求,且性能远高于Python侧循环实现。

基于已聚合列表列的实现

直接在你现有的df_groups结果上做过滤即可,核心是通过list.eval在列表内部计算两个目标字符串首次出现的索引,再比较大小:

pre = 'A'
succ = 'B'

df_groups_filtered = df_groups.filter(
    # 先过滤掉两个目标字符串不全的分组
    pl.col('str_list').list.contains(pre)
    & pl.col('str_list').list.contains(succ)
    # 原生比较两个字符串首次出现的索引先后
    & pl.col('str_list').list.eval(
        pl.arg_where(pl.element() == pre).first()
        < pl.arg_where(pl.element() == succ).first()
    ).first()
)

运行结果和你预期完全一致:

shape: (1, 2)
┌───────┬─────────────────┐
│ group ┆ str_list        │
│ ---   ┆ ---             │
│ i64   ┆ list[str]       │
╞═══════╪═════════════════╡
│ 1     ┆ ["A", "B", "B"] │
└───────┴─────────────────┘

说明:list.eval会直接在Polars Rust引擎内部执行列表元素遍历和索引计算,没有Python侧函数调用开销,大数据量下性能比map_elements实现高10~100倍。

更高性能的实现(跳过中间列表构造)

如果你不需要保留聚合后的str_list列做其他计算,可以直接在分组聚合阶段完成顺序判断,省去构造字符串列表的内存和计算开销:

pre = 'A'
succ = 'B'

df_result = df.group_by('group').agg(
    pl.col('str').alias('str_list'),
    # 布尔列的arg_max会直接返回第一个True的位置,即元素首次出现索引
    (pl.col('str').eq(pre).arg_max() < pl.col('str').eq(succ).arg_max())
    .alias('pre_before_succ')
).filter(
    pl.col('pre_before_succ')
    & pl.col('str_list').list.contains(pre)
    & pl.col('str_list').list.contains(succ)
)

内容的提问来源于stack exchange,提问作者Thomas Lutterbeck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:42:15