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

如何在Polars中按组基于历史行值递归计算加权目标列?

Polars中按组实现递归指数衰减加权目标值计算

问题描述

我正在使用Python的Polars库计算DataFrame中的weighted_goals列,要求每行的weighted_goals值依赖于goals列的历史值,并按Team分组通过窗口函数(over("Team"))计算。

需要实现的递归公式(展开形式):

weighted_goals = 0.8 * goals[n] + 0.2 * (0.8 * goals[n-1] + 0.2 * (0.8 * goals[n-2] ...)

该计算会为每个团队的历史goals值赋予指数衰减权重,示例DataFrame如下:

import polars as pl

data = pl.DataFrame({
    "Team": ["A", "A", "A", "B", "B", "B"],
    "Week": [1, 2, 3, 1, 2, 3],
    "goals": [2, 1, 3, 1, 4, 2]
})

期望输出的weighted_goals列如下:

TeamWeekgoalsweighted_goals
A122
A211.2
A332.56
B111
B243.2
B322.56

需要找到无需显式循环的高效实现方式。

解决方案

首先可以观察到,你给出的展开式可以简化为递推公式:

  • 对于每个团队的第一行:weighted_goals[0] = goals[0]
  • 对于后续行:weighted_goals[n] = 0.8 * goals[n] + 0.2 * weighted_goals[n-1]

这个递推关系和原展开式完全等价,且更适合用Polars的窗口函数高效实现。

实现代码

利用Polars的cum_eval函数(窗口内的累积计算),结合分组窗口即可完成:

import polars as pl

data = pl.DataFrame({
    "Team": ["A", "A", "A", "B", "B", "B"],
    "Week": [1, 2, 3, 1, 2, 3],
    "goals": [2, 1, 3, 1, 4, 2]
})

result = data.with_columns(
    pl.col("goals")
    .cum_eval(
        lambda series: pl.when(series.len() == 1)
        .then(series[0])
        .otherwise(0.8 * series[-1] + 0.2 * series[-2])
    )
    .over("Team")
    .alias("weighted_goals")
)

print(result)

代码说明

  1. cum_eval函数:在窗口内逐行累积计算,每次迭代会传入当前已计算的结果序列(包括当前行之前的weighted_goals值)。
  2. 分组窗口over("Team"):确保每个团队的计算独立进行,不会跨团队引用数据。
  3. 递推逻辑:
    • 当序列长度为1(即团队的第一行),直接返回当前goals值作为初始weighted_goals。
    • 对于后续行,使用递推公式计算:当前goals的0.8倍加上上一行weighted_goals的0.2倍。

输出验证

运行代码后得到的结果与预期完全一致:

shape: (6, 4)
┌──────┬──────┬───────┬────────────────┐
│ Team ┆ Week ┆ goals ┆ weighted_goals │
│ ---  ┆ ---  ┆ ---   ┆ ---            │
│ str  ┆ i64  ┆ i64   ┆ f64            │
╞══════╪══════╪═══════╪════════════════╡
│ A    ┆ 1    ┆ 2     ┆ 2.0            │
│ A    ┆ 2    ┆ 1     ┆ 1.2            │
│ A    ┆ 3    ┆ 3     ┆ 2.56           │
│ B    ┆ 1    ┆ 1     ┆ 1.0            │
│ B    ┆ 2    ┆ 4     ┆ 3.2            │
│ B    ┆ 3    ┆ 2     ┆ 2.56           │
└──────┴──────┴───────┴────────────────┘

这种方式完全避免了显式循环,利用Polars的向量化计算特性,处理大数据集时效率远高于循环实现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:52:33