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

如何在Polars中实现基于日期范围的条件累计求和

问题分析

你原代码的问题在于:group_by('Date1') 后,agg 中的过滤逻辑是**在每个分组内部(即仅当前Date1对应的那一行)**判断条件,而不是让每个Date1和所有行的Date2/Date3做范围匹配,所以无法得到跨行的求和结果。

解决方案

要实现每个Date1匹配所有行的日期范围并求和,需要让每个Date1能访问到全表的Date2/Date3/Value数据,以下是两种可行方法:

方法1:交叉连接+过滤+分组求和

通过交叉连接生成所有Date1与全表行的组合,再过滤符合条件的行后求和,最后补全未匹配的Date1并填0:

import polars as pl

result = (
    # 取出所有Date1
    testDf.select("Date1")
    # 与全表的日期范围和数值列做交叉连接
    .cross_join(testDf.select("Date2", "Date3", "Value"))
    # 过滤Date1落在[Date2, Date3]范围内的行
    .filter((pl.col("Date1") >= pl.col("Date2")) & (pl.col("Date1") <= pl.col("Date3")))
    # 按Date1分组计算符合条件的Value总和
    .group_by("Date1")
    .agg(pl.col("Value").sum().alias("Sum"))
    # 右连接原表的Date1,确保所有原始Date1都被保留
    .right_join(testDf.select("Date1"), on="Date1")
    # 无匹配结果的Date1填充0
    .fill_null(0)
    # 按Date1排序
    .sort("Date1")
)

print(result)

方法2:广播+窗口函数求和

利用broadcast()将单个Date1广播到全表行,结合窗口函数直接计算每个Date1的符合条件的总和:

import polars as pl

result = (
    testDf.with_columns(
        # 广播当前Date1到所有行,过滤符合范围的Value后求和,按Date1分组计算
        pl.col("Value")
        .filter((pl.col("Date1").broadcast() >= pl.col("Date2")) & (pl.col("Date1").broadcast() <= pl.col("Date3")))
        .sum()
        .over("Date1")
        .alias("Sum")
    )
    # 只保留目标列
    .select("Date1", "Sum")
    # 去重(每行的Sum值重复)
    .unique()
    # 无匹配结果的Date1填充0
    .fill_null(0)
    # 按Date1排序
    .sort("Date1")
)

print(result)
验证结果

两种方法都会输出你预期的结果:

shape: (5, 2)
┌────────────┬─────┐
│ Date1      ┆ Sum │
│ ---        ┆ --- │
│ date       ┆ i64 │
╞════════════╪═════╡
│ 2024-04-01 ┆ 0   │
│ 2024-04-06 ┆ 10  │
│ 2024-04-07 ┆ 25  │
│ 2024-04-10 ┆ -15 │
│ 2024-04-11 ┆ 5   │
└────────────┴─────┘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:56