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

使用Polars表达式填充年龄并补全行,构建完整客户年度数据集

Polars 补全年份数据并推算年龄的简洁实现

现有包含缺失年份的Polars DataFrame,部分客户的1999、2000、2001年数据不全,需要补全所有年份,并按每年增长1岁的规则推算年龄。

原始数据

import polars as pl

df = pl.DataFrame({
    "cust_id": [1, 2 ,2, 2, 3, 3],
    "year": [2000,1999,2000,2001,1999,2001],
    "cust_age": [21,31,32,33,44,46]
})

目标结果

target_df = pl.DataFrame({
    "cust_id": [1, 1, 1, 2 ,2, 2, 3, 3, 3 ],
    "year": [1999,2000,2001,1999,2000,2001,1999,2000,2001],
    "cust_age": [20,21,22,31,32,33,44,45,46]
})

Polars 地道实现方案

这里提供两种Polars风格的简洁实现,避免迭代拼接,充分利用其向量化和窗口函数能力:

方法一:交叉连接+窗口函数推算

# 生成所有客户与目标年份的完整组合
full_combinations = (
    df.select("cust_id").unique()
    .join(pl.DataFrame({"year": [1999, 2000, 2001]}), how="cross")
)

# 合并原始数据并推算年龄
result = (
    full_combinations.join(df, on=["cust_id", "year"], how="left")
    .with_columns(
        # 对每个客户,基于已知的年龄和对应年份,计算所有年份的年龄
        pl.col("cust_age").fill_null(
            pl.col("cust_age").filter(pl.col("cust_age").is_not_null()).first()
            + (pl.col("year") - pl.col("year").filter(pl.col("cust_age").is_not_null()).first())
        ).over("cust_id")
    )
    .sort(["cust_id", "year"])
)

方法二:分组聚合+序列生成(更简洁)

result = (
    df
    .group_by("cust_id")
    .agg(
        # 生成1999-2001的年份序列
        pl.int_range(start=1999, end=2002).alias("year"),
        # 基于客户的已知年龄和对应年份,直接推算所有年份的年龄
        (
            pl.col("cust_age").filter(pl.col("cust_age").is_not_null()).first()
            + (pl.int_range(1999, 2002) - pl.col("year").filter(pl.col("cust_age").is_not_null()).first())
        ).alias("cust_age")
    )
    .explode(["year", "cust_age"])
    .sort(["cust_id", "year"])
)

实现说明

  • 两种方法都基于Polars的向量化操作,避免了低效的循环拼接。
  • 核心逻辑:对每个客户,找到其任意一条已知的(year, cust_age)数据,通过当前年份与基准年份的差值推算年龄,确保每年增长1岁的规则准确生效。
  • 方法二更紧凑,直接在分组聚合阶段生成完整的年份和年龄序列,再通过explode展开成行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:25:17