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

如何在Polars中为原DataFrame添加滚动KPI?无索引关联问题

在Polars中保留原始列添加分组滚动KPI的正确姿势

你遇到的核心问题是误用了Polars的group_by().agg()方式做滚动计算——这种聚合操作会把每个组的结果打包成列表,没法和原DataFrame的行一一对应。Polars提供了更简洁的窗口函数方案,结合over子句就能直接在原DataFrame上添加滚动指标,完全不需要额外的合并操作。

先看你的Pandas实现参考

假设你的Pandas代码是这样的:

import pandas as pd

# 测试数据
df_pd = pd.DataFrame({
    "group_id": ["A", "A", "A", "B", "B", "B"],
    "value": [1, 3, 5, 2, 4, 6],
    "other_col": ["x", "y", "z", "p", "q", "r"]
})

# Pandas 分组滚动中位数 + 合并回原表
rolling_median_pd = df_pd.groupby("group_id")["value"].rolling(window=2, min_periods=1).median().reset_index()
df_pd = df_pd.merge(rolling_median_pd.rename(columns={"value": "rolling_median"}), on=["group_id", "level_1"])

Polars的正确实现

Polars的窗口函数可以直接通过over指定分组,然后对目标列应用滚动计算,自动为每一行生成对应值,同时保留所有原始列:

import polars as pl

# 测试数据
df_pl = pl.DataFrame({
    "group_id": ["A", "A", "A", "B", "B", "B"],
    "value": [1, 3, 5, 2, 4, 6],
    "other_col": ["x", "y", "z", "p", "q", "r"]
})

# 直接添加分组滚动中位数列,保留所有原始列
df_pl = df_pl.with_columns(
    pl.col("value")
    .rolling_median(window_size=2, min_periods=1)
    .over("group_id")
    .alias("rolling_median")
)

print(df_pl)

输出结果:

shape: (6, 4)
┌──────────┬───────┬───────────┬────────────────┐
│ group_id ┆ value ┆ other_col ┆ rolling_median │
│ ---      ┆ ---   ┆ ---       ┆ ---            │
│ str      ┆ i64   ┆ str       ┆ f64            │
╞══════════╪═══════╪═══════════╪════════════════╡
│ A        ┆ 1     ┆ x         ┆ 1.0            │
│ A        ┆ 3     ┆ y         ┆ 2.0            │
│ A        ┆ 5     ┆ z         ┆ 4.0            │
│ B        ┆ 2     ┆ p         ┆ 2.0            │
│ B        ┆ 4     ┆ q         ┆ 3.0            │
│ B        ┆ 6     ┆ r         ┆ 5.0            │
└──────────┴───────┴───────────┴────────────────┘

为什么之前的尝试失败?

你之前用group_by().agg()的方式,会把每个组的滚动结果聚合为一个列表(比如组A的滚动中位数是[1.0,2.0,4.0]),这种结构和原DataFrame的行级数据无法直接关联。而over子句是Polars的窗口分组机制,它会为每一行计算其所在分组内的滚动值,结果维度和原DataFrame完全一致,自然不需要额外的合并操作。

扩展:其他滚动KPI的实现

如果需要其他滚动指标(比如滚动均值、滚动最大值),只需要替换对应的滚动函数即可,比如:

df_pl = df_pl.with_columns(
    pl.col("value").rolling_mean(window_size=2, min_periods=1).over("group_id").alias("rolling_mean"),
    pl.col("value").rolling_max(window_size=2, min_periods=1).over("group_id").alias("rolling_max")
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:02:43