Polars中如何用group_by_dynamic忽略日期仅按时间分组?
问题描述
测试数据存储在mwe.csv中,格式如下:
datetime,duration_in_traffic_s 2023-12-20T10:50:43.063641000,221.0 2023-12-20T10:59:09.884939000,219.0 ...(更多不同日期的行)
需求是使用Polars的group_by_dynamic函数,以每10分钟为间隔、1小时为窗口计算duration_in_traffic_s的平均值,且忽略日期,仅按一天中的时间分组(即2023-12-20 10:40和2023-12-21 10:40需归为同一组)。
当前执行的代码如下:
( pl.read_csv("mwe.csv") .with_columns(pl.col("datetime").cast(pl.Datetime)) .sort("datetime") .group_by_dynamic( index_column="datetime", every="10m", period="1h", ) .agg(pl.col("duration_in_traffic_s").mean()) )
但该代码会将不同日期的同一时间分为不同组,无法满足需求。尝试转换为时间类型或浮点数值的方式均无法适配group_by_dynamic的使用,且希望保留时间格式。
解决方案
核心思路是将所有datetime的日期部分统一替换为固定日期(比如2000-01-01),这样所有时间都落在同一天内,再使用group_by_dynamic即可实现按一天内的时间分组,最后提取结果中的时间部分即可。
完整代码实现:
import polars as pl ( pl.read_csv("mwe.csv") .with_columns(pl.col("datetime").cast(pl.Datetime)) # 将所有datetime的日期替换为固定值,仅保留时间部分 .with_columns( fixed_day_dt=pl.col("datetime").dt.replace(year=2000, month=1, day=1) ) .sort("fixed_day_dt") .group_by_dynamic( index_column="fixed_day_dt", every="10m", period="1h", # 可选:设置窗口对齐方式,比如按整点对齐 offset="0m" ) .agg(pl.col("duration_in_traffic_s").mean().alias("avg_duration_s")) # 将结果中的datetime转换为时间格式,仅保留时分秒 .with_columns( time_window=pl.col("fixed_day_dt").dt.time() ) # 移除临时列,保留需要的结果列 .drop("fixed_day_dt") )
代码说明
- 统一日期部分:使用
dt.replace()将所有datetime的日期替换为固定值(如2000-01-01),这样所有数据的时间维度都集中在同一天,group_by_dynamic会基于这一天的时间进行分组。 - 动态分组计算:基于处理后的
fixed_day_dt执行group_by_dynamic,设置every="10m"(分组间隔)和period="1h"(窗口长度),计算窗口内的平均值。 - 保留时间格式:最后将结果中的
fixed_day_dt转换为time类型,得到仅包含时分秒的窗口时间标识,同时移除临时列。
这样处理后,不同日期的同一时间段数据会被合并到同一个窗口中计算平均值,且结果保留了时间格式。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

