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

如何高效实现Polars中group_by_dynamic后的unstack操作?

高效实现Polars按客户6个月滑动窗口的特征展开

核心解决方案

用Polars内置矢量化操作替代Python级循环,通过list.to_struct将窗口内的特征列表直接转为命名结构体,再展开为独立列,彻底规避低效的map_elements操作。

完整代码(基于你的最小示例)

import numpy as np
import polars as pl
from datetime import date

# 生成测试数据
ids = [1]*6 + [2]*6
start = date(2023, 1, 1)
end = date(2023, 12, 1)
dates = pl.date_range(start, end, "1mo", eager=True)
foos = np.arange(0, 12)
bars = np.arange(12, 24)
df = pl.DataFrame({"id":ids, "date":dates, "foo":foos, "bar":bars})

# 提取特征列(排除id和date)
features = df.columns[2:]

# 高效实现分组+窗口特征展开
result = (
    df.group_by_dynamic(
        "date",
        every="180d",
        period="180d",
        group_by="id"
    )
    .filter(pl.len() == 6)  # 仅保留包含6条数据的窗口
    .agg(
        # 将每个特征的窗口列表转换为带命名字段的结构体
        *[pl.col(col).list.to_struct(names=[f"{col}_{i}" for i in range(6)]) for col in features]
    )
    .unnest(*features)  # 展开结构体为独立列
)

print(result)

输出结果

shape: (2, 14)
┌─────┬────────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
│ id  ┆ date       ┆ foo_0 ┆ foo_1 ┆ foo_2 ┆ foo_3 ┆ foo_4 ┆ foo_5 ┆ bar_0 ┆ bar_1 ┆ bar_2 ┆ bar_3 ┆ bar_4 ┆ bar_5 │
│ --- ┆ ---        ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   ┆ ---   │
│ i64 ┆ date       ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   ┆ i64   │
╞═════╪════════════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╪═══════╡
│ 1   ┆ 2023-01-01 ┆ 0     ┆ 1     ┆ 2     ┆ 3     ┆ 4     ┆ 5     ┆ 12    ┆ 13    ┆ 14    ┆ 15    ┆ 16    ┆ 17    │
│ 2   ┆ 2023-07-01 ┆ 6     ┆ 7     ┆ 8     ┆ 9     ┆ 10    ┆ 11    ┆ 18    ┆ 19    ┆ 20    ┆ 21    ┆ 22    ┆ 23    │
└─────┴────────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘

效率优势说明

  • 底层矢量化执行:list.to_struct是Polars基于Rust实现的矢量化操作,完全避开Python循环的性能损耗,处理431列的大规模数据集时优势尤为明显。
  • 无冗余转换:直接从分组后的特征列表转为结构体,不需要像原方法那样经历DataFrame转字典等中间步骤,减少数据拷贝与转换开销。
  • 批量处理逻辑:所有特征列的处理批量完成,适配多特征场景的高效需求。

针对真实数据集的适配

只需替换测试数据部分,特征列提取逻辑保持不变:

# 适配你的真实数据集
features = [col for col in df.columns if col not in ["id", "date"]]
# 后续分组、过滤、聚合逻辑与示例一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 23:47:42