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

如何使用Polars按组内参考值归一化分组数据?

用Polars实现分组参考值归一化

我需要用Polars完成分组条目值的归一化操作——将每组内的value值除以该组中reference_state为ref的对应value值,生成normalised列。

示例数据如下:

import polars as pl

df = pl.from_repr("""
┌──────────┬─────────────────┬───────┐
│ group_id ┆ reference_state ┆ value │
│ ---      ┆ ---             ┆ ---   │
│ i64      ┆ str             ┆ i64   │
╞══════════╪═════════════════╪═══════╡
│ 1        ┆ ref             ┆ 5     │
│ 1        ┆ a               ┆ 3     │
│ 1        ┆ b               ┆ 1     │
│ 2        ┆ ref             ┆ 4     │
│ 2        ┆ a               ┆ 8     │
│ 2        ┆ b               ┆ 2     │
└──────────┴─────────────────┴───────┘
""")

我已经用Pandas实现了该逻辑:

df = df.to_pandas()

for (i, x) in df.groupby("group_id"):
    ref_val = x.loc[x["reference_state"] == "ref"]["value"]
    df.loc[df["group_id"] == i, "normalised"] = x["value"] / ref_val.to_list()[0]
    
pl.from_pandas(df)

期望输出结果:

shape: (6, 4)
┌──────────┬─────────────────┬───────┬────────────┐
│ group_id ┆ reference_state ┆ value ┆ normalised │
│ ---      ┆ ---             ┆ ---   ┆ ---        │
│ i64      ┆ str             ┆ i64   ┆ f64        │
╞══════════╪═════════════════╪═══════╪════════════╡
│ 1        ┆ ref             ┆ 5     ┆ 1.0        │
│ 1        ┆ a               ┆ 3     ┆ 0.6        │
│ 1        ┆ b               ┆ 1     ┆ 0.2        │
│ 2        ┆ ref             ┆ 4     ┆ 1.0        │
│ 2        ┆ a               ┆ 8     ┆ 2.0        │
│ 2        ┆ b               ┆ 2     ┆ 0.5        │
└──────────┴─────────────────┴───────┴────────────┘

Polars实现方案

方法一:窗口函数(推荐)

利用Polars的窗口函数over,直接在分组内筛选参考值并完成计算,代码简洁高效:

result_df = df.with_columns(
    normalised=pl.col("value") / pl.col("value").filter(pl.col("reference_state") == "ref").over("group_id")
)

说明:pl.col("value").filter(...).over("group_id")会在每个group_id分组内,筛选出reference_state为ref的value值,该值会自动广播到当前组的所有行,之后用每行的value除以这个参考值,得到归一化结果。

方法二:分组提取参考值后合并

先提取每个组的参考值,再和原表关联计算,适合需要单独处理参考值的场景:

# 提取每个分组的参考值
ref_values = df.filter(pl.col("reference_state") == "ref").select(
    "group_id", pl.col("value").alias("ref_value")
)

# 关联原表并计算归一化列
result_df = df.join(ref_values, on="group_id").with_columns(
    normalised=pl.col("value") / pl.col("ref_value")
).drop("ref_value")

两种方法都能得到符合预期的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:55:14