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

如何在Polars中将结构体列展开为行

如何在Polars中将结构体列展开为行

看起来你想要把每个结构体里的字段转成单独的行,同时保留各个地区的数值对应关系对吧?这确实不能直接用unnest或explode搞定,得结合几个Polars的操作来实现,我给你一步步拆解:

首先先回顾下你的原始数据:

import polars as pl

df = pl.DataFrame({'EU': {'size': 10, 'GDP': 80},
                   'US': {'size': 100, 'GDP': 800},
                   'AS': {'size': 80, 'GDP': 500}})

原始输出是:

shape: (1, 3)
┌───────────┬───────────┬───────────┐
│ EU        ┆ US        ┆ AS        │
│ ---       ┆ ---       ┆ ---       │
│ struct[2] ┆ struct[2] ┆ struct[2] │
╞═══════════╪═══════════╪═══════════╡
│ {10,80}   ┆ {100,800} ┆ {80,500}  │
└───────────┴───────────┴───────────┘

方法一:转置+展开+透视组合操作

result = (
    df
    # 先转置,把地区列变成行,原来的struct列变成新的"value"列
    .transpose(include_header=True, header_name="region")
    # 展开struct列,得到size和GDP两个数值列
    .unnest("value")
    # 把size/GDP列转成行,生成记录类型的metric列和对应数值
    .melt(id_vars="region", variable_name="metric", value_name="value")
    # 透视回目标结构:以metric为行,地区为列填充数值
    .pivot(index="metric", columns="region", values="value")
    # 调整列顺序,让metric列排在最前面
    .select(["metric", "EU", "US", "AS"])
)

print(result)

运行后就能得到你想要的结果:

shape: (2, 4)
┌────────┬─────┬─────┬─────┐
│ metric ┆ EU  ┆ US  ┆ AS  │
│ ---    ┆ --- ┆ --- ┆ --- │
│ str    ┆ i64 ┆ i64 ┆ i64 │
╞════════╪═════╪═════╪═════╡
│ size   ┆ 10  ┆ 100 ┆ 80  │
│ GDP    ┆ 80  ┆ 800 ┆ 500 │
└────────┴─────┴─────┴─────┘

步骤细节解释

  • .transpose(...):把原DataFrame的行列互换,让原来的地区列名(EU/US/AS)变成新的region列,struct值统一放到value列,此时数据是3行2列的结构。
  • .unnest("value"):把嵌套的struct列拆成单独的数值列,现在数据变成3行3列(region、size、GDP)。
  • .melt(...):将宽表转成窄表,把size和GDP这两个数值列转成metric标记行,同时保留对应的数值和地区信息,此时数据是6行3列。
  • .pivot(...):把窄表转回宽表,以metric为行索引,地区为列,填充对应数值,得到目标的2行4列结构。
  • .select(...):最后调整列的顺序,让metric列处于第一列,符合你的预期格式。

如果你想要封装成类似你设想的expand_structs函数,也可以自己实现:

def expand_structs(df, metric_col_name="metric"):
    return (
        df
        .transpose(include_header=True, header_name="region")
        .unnest("value")
        .melt(id_vars="region", variable_name=metric_col_name, value_name="value")
        .pivot(index=metric_col_name, columns="region", values="value")
        .select([metric_col_name] + df.columns)
    )

# 调用函数
result = expand_structs(df)
print(result)

这样调用起来就和你设想的用法差不多啦!

备注:内容来源于stack exchange,提问作者Phil-ZXX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:54:38