如何自定义格式化polars.Duration类型数据?
如何自定义格式化Polars Duration类型为字符串
初始代码与输出
df = (polars .DataFrame(dict( j=['2023-01-02 03:04:05.111', '2023-01-08 05:04:03.789'], k=['2023-01-02 03:04:05.222', '2023-01-02 03:04:05.456'], )) .select( polars.col('j').str.to_datetime(), polars.col('k').str.to_datetime(), ) .with_columns( l=polars.col('k') - polars.col('j'), ) ) print(df)
运行输出:
j (datetime[μs]) k (datetime[μs]) l (duration[μs]) 2023-01-02 03:04:05.111 2023-01-02 03:04:05.222 111ms 2023-01-08 05:04:03.789 2023-01-02 03:04:05.456 -6d -1h -59m -58s -333ms shape: (2, 3)
尝试格式化时的错误
执行以下代码:
print(df .select( polars.col('l').dt.to_string('%s.%f') ) )
抛出错误:
polars.exceptions.InvalidOperationError: `to_string` operation not supported for dtype `duration[μs]`
解决方法
Polars目前没有为Duration类型提供直接的dt.to_string()自定义格式化方法,可通过以下几种方式实现需求:
方法1:提取时间分量拼接字符串
利用Polars的dt命名空间提取天、小时、分钟、秒等分量,按需拼接成自定义格式:
import polars as pl df_formatted = df.with_columns( formatted_l=pl.format( "{:02d}天{:02d}时{:02d}分{:06.3f}秒", pl.col("l").dt.days(), pl.col("l").dt.hours(), pl.col("l").dt.minutes(), pl.col("l").dt.seconds() + pl.col("l").dt.microseconds() / 1e6 ) ) print(df_formatted)
输出示例:
j (datetime[μs]) k (datetime[μs]) l (duration[μs]) formatted_l 2023-01-02 03:04:05.111 2023-01-02 03:04:05.222 111ms 00天00时00分00.111秒 2023-01-08 05:04:03.789 2023-01-02 03:04:05.456 -6d -1h -59m -58s -333ms -06天-01时-59分-58.333秒 shape: (2, 4)
方法2:转换为总秒数后格式化
如果需要类似%s.%f的秒级格式,可先将Duration转为总秒数再格式化:
df_formatted = df.with_columns( formatted_l=pl.format( "{:.6f}", pl.col("l").dt.total_seconds() ) ) print(df_formatted)
输出示例:
j (datetime[μs]) k (datetime[μs]) l (duration[μs]) formatted_l 2023-01-02 03:04:05.111 2023-01-02 03:04:05.222 111ms 0.111000 2023-01-08 05:04:03.789 2023-01-02 03:04:05.456 -6d -1h -59m -58s -333ms -527998.333000 shape: (2, 4)
方法3:Python UDF实现复杂格式
针对更复杂的自定义逻辑,可使用map_elements调用Python函数处理:
def format_duration(d): days = d.days total_seconds = d.seconds + d.microseconds / 1e6 return f"{days}天{total_seconds:.3f}秒" df_formatted = df.with_columns( formatted_l=pl.col("l").map_elements(format_duration, return_dtype=pl.String) ) print(df_formatted)
注意:UDF性能低于纯Polars表达式,数据量大时优先选用前两种方法。
内容的提问来源于stack exchange,提问作者levant pied
相关产品推荐
相关产品推荐

