为何返回pl.Float32而非pl.Date?Polars日期列类型异常问题
问题根源
你遇到的类型异常原因有两点:
- 初始化DataFrame时,
order_date列全为None,Polars无日期类型上下文,默认将其推断为f32类型(而非预期的pl.Date)。 - 在
when/then逻辑链中,pl.Date类型的常量startdate与f32类型的order_date列混合运算时,Polars会自动进行类型提升——将日期转换为内部存储的浮点天数(19358对应2023-01-01),最终导致新列类型变为f32。
解决方法
方法一:先显式转换order_date为日期类型
先把order_date列强制转为pl.Date,确保后续逻辑中类型统一:
import polars as pl startdate = pl.date(year=2023, month=1, day=1) data = {"customer": ["Mike", "Jan"], "order_date": [None, None]} # 显式将order_date转为Date类型 df = pl.DataFrame(data).with_columns(pl.col("order_date").cast(pl.Date)) (df .with_columns( pl .when(pl.col("order_date").is_null()) .then(startdate) .when(pl.col("order_date")>startdate) .then(pl.col("order_date")) .otherwise(startdate) .alias("startdate_before_override"), ) )
执行后输出:
shape: (2, 3) ┌──────────┬────────────┬───────────────────────────┐ │ customer ┆ order_date ┆ startdate_before_override │ │ --- ┆ --- ┆ --- │ │ str ┆ date ┆ date │ ╞══════════╪════════════╪═══════════════════════════╡ │ Mike ┆ null ┆ 2023-01-01 │ │ Jan ┆ null ┆ 2023-01-01 │ └──────────┴────────────┴───────────────────────────┘
方法二:用coalesce简化逻辑(更推荐)
你的核心需求是"取order_date非空值,否则用startdate",Polars的coalesce函数原生支持这种逻辑,代码更简洁且类型安全:
import polars as pl startdate = pl.date(year=2023, month=1, day=1) data = {"customer": ["Mike", "Jan"], "order_date": [None, None]} df = pl.DataFrame(data).with_columns(pl.col("order_date").cast(pl.Date)) (df .with_columns( pl.coalesce([pl.col("order_date"), startdate]).alias("startdate_before_override") ) )
如果需要保留order_date > startdate的额外判断,可以结合when实现:
(df .with_columns( pl .when(pl.col("order_date") > startdate) .then(pl.col("order_date")) .otherwise(startdate) .alias("startdate_before_override"), ) )
此时order_date已为pl.Date类型,与startdate类型一致,最终新列会保持pl.Date类型。
内容的提问来源于stack exchange,提问作者Balthazar
相关产品推荐
相关产品推荐

