如何在Polars Python API中解构嵌套结构体提取companyName并做空值检查?
使用Polars提取嵌套Struct字段并实现空值检查
初始数据与需求
给定嵌套结构数据,需从Polars DataFrame的positions列(结构体类型)中提取companyName字段,同时实现与以下列表推导式完全一致的空值检查逻辑:
names = ( [ p["company"]["companyName"] for p in data["positions"] if p.get("company") and p.get("company").get("companyName") ] if data.get("positions") else None )
解决方案
情况1:positions为结构体列(对应你给出的Before形态)
此时DataFrame每行是一个单独的positions结构体,直接通过结构体字段访问结合条件判断即可实现需求:
import polars as pl # 构建初始DataFrame data = { "positions": [ {"company": {"companyName": "name1"}}, {"company": {"companyName": "name2"}}, {"company": {"companyName": "name3"}}, # 可添加测试用例:{"company": None}, {} 或 {"company": {"companyName": None}} ] } df = pl.DataFrame(data) # 提取字段并处理空值 result_df = df.with_columns( names=pl.when( # 对应列表推导式的if判断:检查company和companyName非空 pl.col("positions").struct.field("company").is_not_null() & pl.col("positions").struct.field("company").struct.field("companyName").is_not_null() ).then( pl.col("positions").struct.field("company").struct.field("companyName") ).alias("names") ).drop("positions") print(result_df)
运行结果与你期望的After形态一致:
shape: (3, 1) ┌───────┐ │ names │ │ --- │ │ str │ ╞═══════╡ │ name1 │ │ name2 │ │ name3 │ └───────┘
情况2:positions为列表结构体列(原始数据未展开)
如果初始DataFrame是一行一列的列表结构体(shape: (1, 1)),则需要使用pl.list.eval结合pl.element()遍历列表中的每个元素,再通过explode展开为多行:
import polars as pl data = { "positions": [ {"company": {"companyName": "name1"}}, {"company": {"companyName": "name2"}}, {"company": {"companyName": "name3"}}, ] } # 此时构建的DF是一行一列,positions为list[struct] df = pl.DataFrame(data) result_df = df.with_columns( names=pl.col("positions").list.eval( pl.when( pl.element().struct.field("company").is_not_null() & pl.element().struct.field("company").struct.field("companyName").is_not_null() ).then( pl.element().struct.field("company").struct.field("companyName") ) ) ).explode("names").drop("positions") print(result_df)
逻辑说明
pl.struct.field():用于访问结构体中的嵌套字段,若字段不存在或为null,则返回nullpl.when(...).then(...):严格对应列表推导式中的条件判断,仅当company和companyName均非空时才提取值,否则返回nullpl.list.eval():当处理列表类型列时,用于遍历列表内的每个元素(通过pl.element()指代当前元素)explode():将列表列展开为多行,匹配你期望的最终形态
内容的提问来源于stack exchange,提问作者Arko
相关产品推荐
相关产品推荐

