Polars中pl.List(pl.Struct)列拆分异常:为何仅返回单个列?
解决Polars中List(Struct)列拆分为多列表列的问题
问题场景
现有Polars DataFrame中某列的类型为pl.List(pl.Struct),希望将该列拆分为多个由标量值组成的列表列。示例数据如下:
import polars as pl df = pl.DataFrame({ "column_0": [ [{"field_1": "a", "field_2": 1}, {"field_1": "b", "field_2":2}], [{"field_1": "c", "field_2":3}] ] }) col_name = "column_0"
尝试使用以下代码拆分时:
df.select( pl.col(col_name).list.eval( pl.element().struct.unnest() ) )
仅得到最后一个字段的列:
shape: (2, 1) ┌───────────┐ │ column_0 │ │ --- │ │ list[i64] │ ╞═══════════╡ │ [1, 2] │ │ [3] │ └───────────┘
但预期结果是拆分出两个列表列:
shape: (2, 2) ┌────────────┬───────────┐ │ field_1 ┆ field_2 │ │ --- ┆ --- │ │ list[str] ┆ list[i64] │ ╞════════════╪═══════════╡ │ ["a", "b"] ┆ [1, 2] │ │ ["c"] ┆ [3] │ └────────────┴───────────┘
问题原因
list.eval(pl.element().struct.unnest())中,struct.unnest()会返回结构体的所有字段,但list.eval只能处理单个表达式的输出,最终只会保留最后一个字段的计算结果,因此仅得到field_2列。
解决方案
方法1:手动指定字段提取(已知字段名时)
直接针对每个结构体字段,使用list.eval提取并转为列表:
result = df.select( pl.col(col_name).list.eval(pl.element().struct.field("field_1")).alias("field_1"), pl.col(col_name).list.eval(pl.element().struct.field("field_2")).alias("field_2") ) print(result)
方法2:动态提取字段(通用写法)
如果结构体字段未知或数量较多,可先获取字段列表,再动态生成提取表达式:
# 获取结构体的所有字段名 struct_fields = df.select(pl.col(col_name).list.first().struct.fields()).item() # 动态生成提取逻辑 result = df.select( [pl.col(col_name).list.eval(pl.element().struct.field(f)).alias(f) for f in struct_fields] ) print(result)
两种方法执行后都能得到预期的拆分结果。
内容的提问来源于stack exchange,提问作者Pain
相关产品推荐
相关产品推荐

