Python中Polars DataFrame条件替换空值异常问题排查
问题:Polars中使用
pl.when().then()替换空值时新增列而非修改原列 测试Polars DataFrame时,第一列存储字符串或空值,第二列存储数字或空值,其余列均为非空数据。尝试用pl.when().then()替换空值,结果新增了一列而非修改原列,无法得到预期的DataFrame。
初始代码
import polars as pl df = pl.from_repr(""" ┌─────────┬─────────┬─────────┐ │ Column1 | Column2 | Column3 │ │ --- | --- | --- │ │ str | i64 | str │ ╞═════════╪═════════╪═════════╡ │ foo | null | a │ │ null | null | b │ │ bar | 1 | c │ └─────────┴─────────┴─────────┘ """)
原替换代码
df = df.with_columns(pl.when(pl.col("Column1").is_null()).then(pl.lit("String"))) df = df.with_columns(pl.when(pl.col("Column2").is_null()).then(0))
实际结果
shape: (3, 4) ┌─────────┬─────────┬─────────┬─────────┐ │ Column1 ┆ Column2 ┆ Column3 ┆ literal │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ str ┆ i32 │ ╞═════════╪═════════╪═════════╡ │ foo ┆ null ┆ a ┆ 0 │ │ null ┆ null ┆ b ┆ 0 │ │ bar ┆ 1 ┆ c ┆ null │ └─────────┴─────────┴─────────┴─────────┘
预期结果
shape: (3, 3) ┌─────────┬─────────┬─────────┐ │ Column1 ┆ Column2 ┆ Column3 │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ str │ ╞═════════╪═════════╪═════════╡ │ foo ┆ 0 ┆ a │ │ String ┆ 0 ┆ b │ │ bar ┆ 1 ┆ c │ └─────────┴─────────┴─────────┘
问题原因
- 缺少
.otherwise()分支:当前pl.when().then()只定义了条件满足时的取值,未指定不满足条件时的行为,此时不满足条件的行会返回null,而非保留原列的值。 - 未指定目标列名:
with_columns默认会将新生成的表达式结果作为新增列加入DataFrame,而非覆盖原列。若要修改原列,需要通过.alias()指定原列名,让表达式结果覆盖原列。
修正后的代码
方式一:使用.alias()指定原列名 + .otherwise()保留原数据
df = df.with_columns( pl.when(pl.col("Column1").is_null()) .then(pl.lit("String")) .otherwise(pl.col("Column1")) .alias("Column1") ) df = df.with_columns( pl.when(pl.col("Column2").is_null()) .then(pl.lit(0, dtype=pl.Int64)) # 显式指定类型匹配原列的i64 .otherwise(pl.col("Column2")) .alias("Column2") )
方式二:更简洁的列方法链式调用
df = df.with_columns( pl.col("Column1").when(pl.col("Column1").is_null()).then("String").otherwise(pl.col("Column1")), pl.col("Column2").when(pl.col("Column2").is_null()).then(0).otherwise(pl.col("Column2")) )
方式三:针对空值替换的专用方法fill_null(更简洁)
如果只是单纯替换空值,Polars提供了更直接的fill_null方法:
df = df.with_columns( pl.col("Column1").fill_null("String"), pl.col("Column2").fill_null(0) )
执行任意一种修正代码后,都能得到预期的DataFrame。
内容的提问来源于stack exchange,提问作者user11028193
相关产品推荐
相关产品推荐

