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

优化Polars扁平DataFrame按表拆分的高效实现方案

多数据库Polars DataFrame拆分优化方案

需求背景

我们有一个扁平结构的Polars DataFrame,用于存储多数据库的结构化数据,包含以下字段:

  • db_id:数据库唯一标识
  • table_id:表唯一标识(不同数据库可共享相同表)
  • column_id:列唯一标识(不同数据库可共享相同列)
  • data:存储多值的列表字段

核心目标是按table_id拆分出独立的DataFrame:每个结果DataFrame的列由对应表的所有column_id加上db_id组成,data字段中的元素需要展开后对应到列的位置,完成转置与展开操作。

各版本实现与性能对比

初始实现

直接按table_id分组后进行透视+展开,Python循环处理每个分组,开销较大:

def initial_split(df: pl.DataFrame) -> dict[str, pl.DataFrame]:
    table_dfs = {}
    for table_id, group in df.group_by("table_id"):
        # 透视后展开所有列的列表值
        pivoted = group.pivot(index="db_id", columns="column_id", values="data")
        exploded = pivoted.explode(pl.exclude("db_id"))
        table_dfs[table_id] = exploded
    return table_dfs

性能:处理250万行数据耗时70分钟

第一次优化

先全局展开data字段,再分组透视,减少分组内的展开操作开销:

def optimized_split(df: pl.DataFrame) -> dict[str, pl.DataFrame]:
    # 先展开所有data列表,避免分组内重复操作
    exploded_df = df.explode("data")
    table_dfs = {}
    for table_id, group in exploded_df.group_by("table_id"):
        # 直接透视得到结构化结果
        pivoted = group.pivot(index="db_id", columns="column_id", values="data")
        table_dfs[table_id] = pivoted
    return table_dfs

性能:处理250万行数据耗时10分钟

最终高效方案

利用Polars的矢量化map_groups替代Python循环,完全在Polars内部处理分组逻辑,最大化性能:

def high_performance_split(df: pl.DataFrame) -> dict[str, pl.DataFrame]:
    # 全局展开data
    exploded_df = df.explode("data")
    # 分组后批量执行透视,返回字典格式
    grouped_result = exploded_df.group_by("table_id").map_groups(
        lambda group: group.pivot(index="db_id", columns="column_id", values="data")
    )
    # 转换为table_id到DataFrame的映射
    return {tid: df for tid, df in grouped_result.items()}

性能:处理250万行数据仅需50秒

性能测试结果

测试数据集:250万行扁平结构Polars DataFrame

  • 初始实现:70分钟
  • 第一次优化:10分钟
  • 最终高效方案:50秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 06:15:17