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

如何用Polars原生表达式按条件从指定列填充前置值?

Polars 原生方法实现同组内按count关联前值需求

问题场景

现有如下Polars DataFrame:

df = pl.DataFrame(
    {
        'val': [9, 7, 9, 11, 2, 5],
        'count': [1, 2, 1, 2, 1, 2],
        'id': [1, 1, 2, 2, 3, 3],
    }
)

需要新增列prev_val,规则是:同一id分组内,取count值减1对应行的val,当count=1时(减1后无对应行)填充null,期望结果如下:

┌─────┬───────┬─────┬──────────┐
│ val ┆ count ┆ id  ┆ prev_val │
│ --- ┆ ---   ┆ --- ┆ ---      │
│ i64 ┆ i64   ┆ i64 ┆ i64      │
╞═════╪═══════╪═════╪══════════╡
│ 9   ┆ 1     ┆ 1   ┆ null     │
│ 7   ┆ 2     ┆ 1   ┆ 9        │
│ 9   ┆ 1     ┆ 2   ┆ null     │
│ 11  ┆ 2     ┆ 2   ┆ 9        │
│ 2   ┆ 1     ┆ 3   ┆ null     │
│ 5   ┆ 2     ┆ 3   ┆ 2        │
└─────┴───────┴─────┴──────────┘

试过map_rows和UDF,但Polars官方不推荐这类方法,想找原生表达式的实现方式。

原生实现方案

方案1:分组后用shift(适合同组内count按顺序排列的场景)

示例里每个id下的行是按count从小到大排好的,直接对分组后的val列做shift(1)就能得到结果:

df.with_columns(
    prev_val=pl.col('val').shift(1).over('id')
)

方案2:通用关联法(适合count不连续或排序混乱的场景)

如果同组内count不是按顺序排的,或者存在非连续的count值,可以用分组过滤的方式匹配对应值:

df.with_columns(
    prev_val=pl.col('val')
        .filter(pl.col('count') == pl.col('count') - 1)
        .first()
        .over('id')
)

或者用自关联的方式,逻辑更直观:

df.join(
    df.select(pl.col('id'), pl.col('count').alias('match_count'), pl.col('val').alias('prev_val'))
        .with_columns(match_count=pl.col('match_count') + 1),
    left_on=['id', 'count'],
    right_on=['id', 'match_count'],
    how='left'
).drop('match_count')

以上都是Polars原生表达式实现,不用依赖UDF或map_rows,性能更符合Polars的设计初衷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:37:39