Polars中按%YW%W格式将字符串转为日期失败的问题
问题描述
我有一个Polars DataFrame,其中包含格式为%YW%W的日期列(如2026W03)。我尝试将该列转换为日期类型,编写了如下代码:
agg_pivoted_df = pivoted_df.with_columns([ pl.col(col).cum_sum().alias(col) for col in pivoted_df.columns if col != "year_week" ] + [pl.col("year_week").str.replace("W", "").str.to_date("%Y%W").dt.offset_by("2d")] )
但代码运行失败,报错信息如下:
InvalidOperationError: conversion from
strtodatefailed in column 'year_week' for 45 out of 45 values: ["202351", "202511", … "202520"]You might want to try:
- setting
strict=Falseto set values that cannot be converted tonull- using
str.strptime,str.to_date, orstr.to_datetimeand providing a format string
我尝试改用strptime(pl.Date, fmt)仍得到相同结果。根据chrono文档,我使用的格式应该匹配日期,也尝试过添加双引号、使用ISO 8601规范,但结果一致。我使用polars1.37.0、python3.13.3,请问在Polars中解析2026W03这类日期的正确方法是什么?
解决方法
Polars依赖chrono库处理日期解析,单独的%Y%W格式(年份+周数)无法确定具体日期——必须补充周几的信息,或者使用完整的ISO周日期格式。以下是两种可行方案:
方案1:补充周几信息直接解析
不需要替换原始字符串中的"W",在格式串中加入周几占位符(比如%u代表周一为1,符合ISO周的起始规则),或者直接给原始字符串拼接固定周几标识:
agg_pivoted_df = pivoted_df.with_columns([ pl.col(col).cum_sum().alias(col) for col in pivoted_df.columns if col != "year_week" ] + [ # 解析为该周的周一,若失败则尝试周日 pl.col("year_week").str.to_date("%YW%W%u", strict=False).fill_null( pl.col("year_week").str.to_date("%YW%W%w") ) ])
或者更简单的拼接方式:
agg_pivoted_df = pivoted_df.with_columns([ pl.col(col).cum_sum().alias(col) for col in pivoted_df.columns if col != "year_week" ] + [ # 拼接"1"表示周一,再解析 pl.col("year_week").str.concat("1").str.to_date("%YW%W%u") ])
方案2:转换为ISO 8601周格式解析
将原始字符串的W替换为-W,变成标准ISO周格式(如2026-W03),再用%G-%V格式解析(%G对应ISO年份,%V对应ISO周数):
agg_pivoted_df = pivoted_df.with_columns([ pl.col(col).cum_sum().alias(col) for col in pivoted_df.columns if col != "year_week" ] + [ pl.col("year_week").str.replace("W", "-W").str.to_date("%G-%V").dt.offset_by("2d") ])
解析后默认映射到该周的周一,可通过dt.offset_by调整到目标日期(比如加2天到周三)。
额外提示
如果不需要指定具体周几,也可以结合strict=False和周起始/结束日期方法:
pl.col("year_week").str.replace("W", "-W").str.to_date("%G-%V", strict=False).dt.week_start()
内容的提问来源于stack exchange,提问作者Pollastre

