Polars:将duration转换为小时/分钟/秒的整数数值
解决Polars中Duration类型转小时/分钟/秒整数的问题
这不是Bug,是你对Duration类型的操作逻辑理解有误。Polars里的dt命名空间是专门为Datetime时间点类型设计的,而你计算得到的是Duration时间间隔类型,两类的操作API并不通用。
错误原因分析
你执行pl.col('dt1') - pl.col('dt1').dt.date()得到的是一个duration[μs]类型的结果(表示从当天0点到目标时间的间隔),这类值代表的是时间长度,而非具体的时间点,因此无法使用dt.hour()这类针对时间点的提取方法。
正确解决方案
方案1:获取总时长的整数数值
如果你需要的是时间间隔对应的总小时、总分钟或总秒数,可以使用Duration类型专属的dt.total_xxx()方法,再将结果转为整数:
from datetime import datetime import polars as pl dx = pl.DataFrame({'dt1': datetime(2024, 1, 12, 13, 45)}) result = dx.select( pl.col('dt1').alias('原始时间'), # 转总小时数 (pl.col('dt1') - pl.col('dt1').dt.date()).dt.total_hours().cast(pl.Int32).alias('总小时'), # 转总分钟数 (pl.col('dt1') - pl.col('dt1').dt.date()).dt.total_minutes().cast(pl.Int32).alias('总分钟'), # 转总秒数 (pl.col('dt1') - pl.col('dt1').dt.date()).dt.total_seconds().cast(pl.Int32).alias('总秒数') ) print(result)
输出结果:
shape: (1, 4) ┌─────────────────────┬────────┬────────┬────────┐ │ 原始时间 ┆ 总小时 ┆ 总分钟 ┆ 总秒数 │ │ --- ┆ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ i32 ┆ i32 ┆ i32 │ ╞═════════════════════╪════════╪════════╪════════╡ │ 2024-01-12 13:45:00 ┆ 13 ┆ 825 ┆ 49500 │ └─────────────────────┴────────┴────────┴────────┘
方案2:提取时分秒分量
如果你只是想提取时间间隔对应的小时、分钟、秒分量(比如例子中的13小时、45分钟),可以先将Duration转为Datetime类型,再使用dt命名空间的方法:
dx.select( (pl.col('dt1') - pl.col('dt1').dt.date()) .cast(pl.Datetime) .dt.hour().alias('小时'), (pl.col('dt1') - pl.col('dt1').dt.date()) .cast(pl.Datetime) .dt.minute().alias('分钟'), (pl.col('dt1') - pl.col('dt1').dt.date()) .cast(pl.Datetime) .dt.second().alias('秒') )
输出结果:
shape: (1, 3) ┌──────┬────────┬──────┐ │ 小时 ┆ 分钟 ┆ 秒 │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞══════╪════════╪══════╡ │ 13 ┆ 45 ┆ 0 │ └──────┴────────┴──────┘
核心区别
- Datetime类型:代表具体时间点,用
dt.hour()/dt.minute()提取时间分量 - Duration类型:代表时间长度,用
dt.total_hours()/dt.total_minutes()获取总时长
内容的提问来源于stack exchange,提问作者user2304916
相关产品推荐
相关产品推荐

