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

如何在Polars中无需循环自动展开多层嵌套Struct列?

扁平化Polars中多层嵌套Struct的更优方案

你当前的循环方案虽然可行,但Polars提供了更简洁的函数式实现方式,无需手动循环和重复赋值DataFrame,下面是几种实用方法:

1. 递归生成扁平化选择表达式

直接遍历所有嵌套字段,生成一次性展开所有Struct的选择逻辑,还能自定义展开后的字段命名规则:

def flatten_exprs(expr: pl.Expr) -> list[pl.Expr]:
    if isinstance(expr.dtype, pl.Struct):
        return [
            pl.col(f"{expr.name}.{field}").alias(f"{expr.name}_{field}")
            for field in expr.dtype.fields
        ]
    return [expr]

# 生成所有字段的扁平化表达式
flat_exprs = []
for col in df.columns:
    flat_exprs.extend(flatten_exprs(pl.col(col)))

# 生成最终的扁平化DataFrame
flat_df = df.select(flat_exprs)

这种方式会把嵌套字段用下划线拼接命名(比如user.address.zip变成user_address_zip),能有效避免字段名冲突。

2. 递归调用unnest处理全层级Struct

写一个递归函数自动识别并展开所有层级的Struct,逻辑清晰且符合函数式风格:

def flatten_df(df: pl.DataFrame) -> pl.DataFrame:
    struct_cols = [col for col in df if isinstance(df[col].dtype, pl.Struct)]
    if not struct_cols:
        return df
    return flatten_df(df.unnest(struct_cols))

# 直接调用得到结果
flat_df = flatten_df(df)

这个函数会逐层展开所有Struct列,直到DataFrame中不存在任何Struct类型的列为止。

3. 用until函数链式处理(Polars 0.19+)

利用Polars的until方法配合pipe,可以一行代码完成递归展开,完全无显式循环:

from functools import partial

# 判断是否还有Struct列
has_struct = lambda df: any(isinstance(dt, pl.Struct) for dt in df.dtypes.values())

# 重复执行unnest直到没有Struct列
flat_df = df.pipe(partial(pl.DataFrame.until, has_struct, lambda df: df.unnest()))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:15:32