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

如何在Polars中展开多结构体列并加后缀避免DuplicateError

在Polars中递归扁平化结构体列并自动消歧重复字段

当你有多个结构相同的结构体列时,直接调用unnest()会因为字段名重复触发DuplicateError。以下是两种解决方案,覆盖从简单场景到复杂嵌套的需求:

方法一:手动展开并重命名(适合少量列场景)

如果结构体列数量不多、嵌套层级浅,可以逐个展开并重命名字段,手动避免冲突:

import polars as pl

nest = pl.DataFrame({
    'a':[{'x':1,'y':10},{'x':2,'y':20},],
    'b':[{'x':3,'y':30},{'x':4,'y':40},]    
})

result = (
    nest
    .unnest("a")
    .rename({"x": "x_a", "y": "y_a"})
    .unnest("b")
    .rename({"x": "x_b", "y": "y_b"})
)

print(result)

输出结果:

shape: (2, 4)
┌─────┬─────┬─────┬─────┐
│ x_a ┆ y_a ┆ x_b ┆ y_b │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╪═════╡
│ 1   ┆ 10  ┆ 3   ┆ 30  │
│ 2   ┆ 20  ┆ 4   ┆ 40  │
└─────┴─────┴─────┴─────┘

方法二:通用递归扁平化函数(支持复杂嵌套)

如果需要处理大量结构体列或深层嵌套数据,可编写递归函数,自动遍历所有结构体列,用「子字段名+分隔符+父列名」的规则重命名字段,彻底解决命名冲突:

import polars as pl

def flatten_structs(df: pl.DataFrame, sep: str = "_") -> pl.DataFrame:
    # 循环处理直到DataFrame中无结构体列
    while any(pl.col(col).dtype.is_struct() for col in df.columns):
        # 筛选所有结构体类型的列
        struct_columns = [col for col in df.columns if pl.col(col).dtype.is_struct()]
        for col in struct_columns:
            # 获取结构体的字段名列表
            field_names = df.schema[col].fields
            # 重命名结构体内部字段,拼接父列名作为后缀
            renamed_struct = pl.col(col).struct.rename_fields([f"{field}{sep}{col}" for field in field_names])
            # 展开结构体并删除原列
            df = df.with_columns(renamed_struct.unnest()).drop(col)
    return df

# 应用函数处理示例数据
nest = pl.DataFrame({
    'a':[{'x':1,'y':10},{'x':2,'y':20},],
    'b':[{'x':3,'y':30},{'x':4,'y':40},]    
})

result = flatten_structs(nest)
print(result)

这个函数支持任意深度的嵌套结构体,比如遇到a: {'x': {'z': 1}, 'y': 10}这类多层嵌套数据时,会自动展开为z_x_a、y_a这类带完整路径的字段名,从根源避免重复命名问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:17:29