Python Polars中时长字符串转换失败问题求助
问题:Polars中无法将圈速字符串转换为Duration类型
我有一些圈速(lap times)数据为pl.String类型,使用strptime转换为pl.Duration时失败,但常规日期时间转换正常。其中冒号前的分钟、点前的秒始终为两位,毫秒始终为三位,且圈速均小于2分钟。
代码示例:
df = pl.DataFrame({ "lap_time": ["01:14.007", "00:53.040", "01:00.123"] }) df = df.with_columns( # pl.col('release_date').str.to_date("%B %d, %Y"), # 可正常工作 pl.col('lap_time').str.to_time("%M:%S.%3f").cast(pl.Duration), # 转换失败 )
我按照Polars的strptime文档使用了chrono的格式说明符,尝试了.%f、.%3f、%.3f等格式,转换均失败。尝试转为pl.Time也失败,报错:
ComputeError: strict conversion to dates failed, maybe set strict=False
设置strict=False后,整个Series全为null值。请问是我遗漏了什么,还是chrono或python-polars的异常行为?
解决方案
问题根源:
str.to_time()是用于解析一天中的具体时间点(如09:30:00),而圈速属于时间段,不符合时间点的解析规则,因此直接转换会失败;同时Polars的str模块没有直接支持将这种时间段字符串转为Duration的方法。正确实现方式:拆分字符串中的分钟、秒、毫秒部分,分别计算后组合成
Duration,以下两种方法均可:
方法一:拆分字符串后结构化处理
import polars as pl df = pl.DataFrame({ "lap_time": ["01:14.007", "00:53.040", "01:00.123"] }) df = df.with_columns( lap_duration=pl.col("lap_time") .str.split(r"[:.]") .list.eval(pl.element().cast(pl.Int64)) .struct.rename_fields(["minutes", "seconds", "milliseconds"]) .apply(lambda x: pl.duration( minutes=x["minutes"], seconds=x["seconds"], milliseconds=x["milliseconds"] )) )
方法二:正则提取各时间分量
import polars as pl df = pl.DataFrame({ "lap_time": ["01:14.007", "00:53.040", "01:00.123"] }) df = df.with_columns( minutes=pl.col("lap_time").str.extract(r"^(\d{2}):").cast(pl.Int64), seconds=pl.col("lap_time").str.extract(r":(\d{2}).").cast(pl.Int64), milliseconds=pl.col("lap_time").str.extract(r".(\d{3})$").cast(pl.Int64) ).with_columns( lap_duration=pl.duration( minutes=pl.col("minutes"), seconds=pl.col("seconds"), milliseconds=pl.col("milliseconds") ) ).drop(["minutes", "seconds", "milliseconds"])
- 验证效果:两种方法都能正确将字符串转为
pl.Duration类型,例如"01:14.007"会被转换为1 minutes 14 seconds 7 milliseconds。
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

