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

如何在Polars中基于前一行值高效计算新列?

在Polars中高效实现依赖前一行值的列计算(替代map_rows)

针对你需要计算依赖前一行结果的Event列的需求,用map_batches替代map_rows是最符合Polars风格且高效的解决方案,以下是具体实现和说明:

核心实现代码

import polars as pl
import numpy as np

def calculate_event(time_series: pl.Series, minutes_series: pl.Series) -> pl.Series:
    # 转换为numpy数组以提升循环效率
    t = time_series.to_numpy()
    m = minutes_series.to_numpy()
    event = np.empty_like(t)
    
    # 设置初始值:第一行的Event值按规则取t[0]+m[0]
    event[0] = t[0] + m[0]
    
    # 批量循环计算后续行
    for i in range(1, len(t)):
        if t[i] > event[i-1]:
            event[i] = event[i-1]
        else:
            event[i] = t[i] + m[i]
    
    return pl.Series(event, dtype=pl.Float64)

# 应用到DataFrame
df = df.with_columns(
    pl.struct(["Time", "Minutes"])
    .map_batches(lambda s: calculate_event(s["Time"], s["Minutes"]))
    .alias("Event")
)

为什么这个方案比map_rows高效?

  • map_rows是逐行调用Python函数,每一行都有函数调用的开销,数据量越大效率越低;
  • map_batches是按批处理整个列数据,一次性将整列(或分块)传入函数,配合numpy数组的底层优化,循环效率比逐行处理提升几个数量级。

补充说明

  1. 初始值调整:如果第一行的Event值需要特殊规则,直接修改event[0]的赋值即可;
  2. 超大规模数据:如果数据量达到千万级以上,还可以考虑用Polars的Rust UDF进一步优化,但上述方案对绝大多数场景已经足够高效;
  3. 类型适配:如果你的Time和Minutes是整数类型,可将dtype=pl.Float64改为对应整数类型(如pl.Int64)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:00:16