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

如何在Polars中计算当前行下方x行的rolling_sum?求更优方案

计算当前行下方x行的滚动求和(Rolling Sum)

我需要实现基于当前行下方x行的滚动求和,而非常规的上方行。目前我有两种实现方案,想对比哪种更优(计算效率更高/代码更简洁可读):

方案一:两次排序实现

先按分组键和排序键降序排列,计算滚动求和后再恢复原顺序:

import polars as pl

# 测试数据集
df = pl.DataFrame({
        "Date": [1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
        "Close": [-1, 1, 2, 3, 4, 4, 3, 2, 1, -1],
        "Company": ["A", "A", "A","A", "A",  "B", "B", "B", "B", "B"]
    })

(
    df
    .sort(by=["Company", "Date"], descending=[True, True])
    .with_columns(
        pl.col("Close").rolling_sum(3).over("Company").alias("Cumsum_lead")
    )
    .sort(by=["Company", "Date"], descending=[False, False])
)

方案二:无需排序,用Shift实现

直接通过滚动求和后偏移,实现“取当前行下方行”的效果:

(
    df
    .with_columns(
        pl.col("Close")
        .rolling_sum(3)
        .shift(-2)
        .over("Company").alias("Cumsum_lead")
    )
)

方案对比与优劣势分析

1. 计算效率

  • Shift方案更高效:排序操作的时间复杂度为O(n log n),两次排序会带来额外的CPU和内存开销;而Shift操作是线性时间O(n),无需额外排序,在处理大型数据集时性能优势会非常明显。
  • 排序方案:即使Polars的排序已经做了优化,仍无法避免两次排序的损耗,数据量越大,差距越显著。

2. 代码简洁性与可读性

  • Shift方案更胜一筹:代码逻辑直接,无需理解“倒序计算再正序恢复”的绕弯逻辑,一眼就能看出是通过滚动求和加偏移来实现目标;排序方案的可读性相对较弱,需要额外梳理排序前后的行对应关系。

3. 注意事项

使用Shift方案时,要注意窗口大小和偏移量的对应关系:

  • 如果需要计算当前行+下方n-1行的滚动求和(窗口大小为n),偏移量应为-(n-1),比如窗口大小3对应shift(-2);
  • 如果需求是仅下方n行(不含当前行),则需要调整为pl.col("Close").shift(1).rolling_sum(n).over("Company")。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:23:27