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

如何基于日期列的年份对Polars LazyFrame进行透视?

Polars LazyFrame 按日期年份透视的正确实现

输入数据

data = {
    'text': ['text A', 'text B', 'text A', 'text A', 'text B', 'text C'],
    'length': [7, 1, 4, 0, 2, 0],
    'date': [20210101, 20231003, 20220808, 20210616, 20210203, 20220419]
}

ldf = pl.LazyFrame(data)

错误尝试与问题

原代码手动指定年份且运行报错:

query = (
    ldf
        .group_by(pl.col('date').cast(pl.String).str.slice(0, 4).alias('year'), pl.col('text')).agg(
            pl.col('length').sum().filter(pl.col('year') == '2021').alias('2021'),
            pl.col('length').sum().filter(pl.col('year') == '2022').alias('2022'),
            pl.col('length').sum().filter(pl.col('year') == '2023').alias('2023'),
        )
)

报错信息:

ComputeError: column 'year' not available in schema Schema:
name: text, data type: Utf8
name: length, data type: Int64
name: date, data type: Int64

错误原因:year是group_by中临时生成的别名,并非原始数据列,在agg的表达式上下文里无法直接引用;同时分组逻辑错误,每组的year是固定值,过滤操作无意义。

期望输出

grp_texts  2021  2022  2023
    text A     7     4     0
    text B     2     0     1
    text C     0     0     0

正确实现方法

方法一:动态生成年份列(推荐,无需手动指定年份)

通过提取年份、分组聚合、透视三步完成,自动识别所有存在的年份:

result = (
    ldf
    # 从整数日期中提取年份,转字符串用于后续列名
    .with_columns(year=pl.col("date") // 10000)
    # 按文本和年份分组,计算长度总和
    .group_by("text", "year")
    .agg(pl.col("length").sum().alias("total_length"))
    # 透视:将年份转为列,缺失值填充0
    .pivot(
        index="text",
        columns="year",
        values="total_length",
        fill_value=0
    )
    # 重命名列匹配期望输出
    .rename({"text": "grp_texts"})
)

print(result.collect())

方法二:手动指定年份(适用于固定年份场景)

先将年份转为数据列,再按文本分组,针对每个年份过滤求和:

result = (
    ldf
    .with_columns(year=pl.col("date") // 10000)
    .group_by("text")
    .agg(
        pl.col("length").filter(pl.col("year") == 2021).sum().alias("2021"),
        pl.col("length").filter(pl.col("year") == 2022).sum().alias("2022"),
        pl.col("length").filter(pl.col("year") == 2023).sum().alias("2023"),
    )
    .rename({"text": "grp_texts"})
)

print(result.collect())

说明

  • 整数除法//10000提取年份比字符串切片更高效,避免类型转换开销;
  • 方法一的透视操作会自动处理所有存在的年份,无需手动维护年份列表,扩展性更强;
  • 两种方法最终输出均匹配期望结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:18:28