如何在Polars中对struct类型列执行fill_null操作?
问题背景
当使用dfcompare = (df0 == df1)比较两个Polars DataFrame时,null值不会被视为相等(不像join操作有匹配null的选项)。对于普通字段可以填充对应类型的“空值”,但struct类型列不知道该用什么值填充,尝试两种方式均报错。目前通过unnest展开子字段填充可行,但想了解:
- 如何构造正确的struct字面量传入
fill_null这类函数 - 如何添加硬编码的struct类型列
解决方法
1. 构造struct字面量填充null
要给struct类型列填充null,需构造和原列字段名、数据类型完全匹配的struct表达式,正确方式是用pl.struct包裹多个pl.lit,明确指定每个子字段的值与类型:
import polars as pl df = pl.DataFrame( { "int": [1, 2, None], "data" : [dict(a=1,b="b"),dict(a=11,b="bb"),None] } ) # 正确填充struct类型null值 df3 = df.with_columns( pl.col("data").fill_null( pl.struct( a=pl.lit(0, dtype=pl.Int64), b=pl.lit("", dtype=pl.String) ) ) ) print(df3)
输出:
shape: (3, 2) ┌──────┬─────────────┐ │ int ┆ data │ │ --- ┆ --- │ │ i64 ┆ struct[2] │ ╞══════╪═════════════╡ │ 1 ┆ {1,"b"} │ │ 2 ┆ {11,"bb"} │ │ null ┆ {0,""} │ └──────┴─────────────┘
如果不确定原struct的类型,可通过df.schema["data"]查看。
2. 添加硬编码的struct类型列
添加硬编码struct列时,同样用pl.struct结合pl.lit定义子字段,再用alias命名新列:
# 添加硬编码struct列 df4 = df.with_columns( pl.struct( x=pl.lit(99, dtype=pl.Int64), y=pl.lit("default", dtype=pl.String) ).alias("default_struct") ) print(df4)
输出:
shape: (3, 3) ┌──────┬─────────────┬───────────────────┐ │ int ┆ data ┆ default_struct │ │ --- ┆ --- ┆ --- │ │ i64 ┆ struct[2] ┆ struct[2] │ ╞══════╪═════════════╪═══════════════════╡ │ 1 ┆ {1,"b"} ┆ {99,"default"} │ │ 2 ┆ {11,"bb"} ┆ {99,"default"} │ │ null ┆ {null,null} ┆ {99,"default"} │ └──────┴─────────────┴───────────────────┘
原尝试报错原因
- 直接传原生字典:Polars的
fill_null不接受原生字典作为struct类型填充值,必须用Polars表达式构造struct pl.struct(dict(a=0,b="")):这种方式构造的子字段类型可能与原列不匹配(比如原列a是Int64,这里0默认是Int32),且Polars推荐用关键字参数指定struct字段,更清晰不易出错
内容的提问来源于stack exchange,提问作者JL Peyret
相关产品推荐
相关产品推荐

