跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何在 Pandas 中按固定时间间隔向下取整而不改变时间序列长度

本文介绍使用 pd.Series.dt.floor() 对时间戳列进行等宽时间桶对齐的方法,确保重采样后数据形状不变,适用于分钟级分组、特征工程中的时间标准化等场景。 本文介绍使用 `pd.series.dt.floor()` 对时间戳列进行等宽时间桶对齐的方法,确保重采样后数据形状不变,适用于分钟级分组、特征工程中的时间标准化等场景。 在时间序列处理中,常需将原始时间戳对齐到指定频率(如每10分钟一个桶),但又 不能改变原始数据的行数与结构 ——即不允许使用 resample() 或 groupby() 导致聚合、丢弃或新增行。此时,dt.floor() 是最直接、高效且保形(shape-preserving)的解决方案。 dt.floor('10min') 的作用是:对每个时间戳向下取整至最近的、能被10分钟整除的时刻。例如: '2020-01-01 00:03:00' → '2020-01-01 00:00:00' '2020-01-01 00:12:00' → '2020-01-01 00:10:00' '2020-01-01 00:22:00' → '2020-01-01 00:20:00' 该操作逐元素执行,输出 Series 长度严格等于输入,完美满足“保持 size 不变”的核心需求。 以下是完整实现代码:
import pandas as pd # 原始数据(注意:日期格式含不规范分隔符,需 robust 解析) bf_data = pd.DataFrame({ "ts": ['2020-1-1 00:03:00', '2020-1-1 00:12:00', '2020-1-1 00:07:00', '2020-1-1 00:18:00', '2020-1-1 00:22:00'], "values": [0.2, 0.3, 0.5, 0.9, 1.0] }) # 关键步骤:转为 datetime → 向下取整至 10 分钟 → 格式化为字符串(可选) bf_data['ts'] = ( pd.to_datetime(bf_data['ts']) # 安全解析任意格式时间字符串 .dt.floor('10min') # 按 10 分钟桶向下取整(保形!) .dt.strftime('%Y-%-m-%-d %H:%M:%S') # 还原为指定字符串格式(Linux/macOS 用 %-m;Windows 请改用 %m) ) print(bf_data)
输出结果:
ts values 0 2020-1-1 00:00:00 0.2 1 2020-1-1 00:10:00 0.3 2 2020-1-1 00:00:00 0.5 3 2020-1-1 00:10:00 0.9 4 2020-1-1 00:20:00 1.0
✅ 优势总结 : 零聚合、零丢失 :不调用 resample/groupby,原始每行独立映射,行列数完全一致; 语义清晰 :floor('10min') 明确表达“归入前一个10分钟桶”的业务逻辑; 性能优异 :基于向量化 datetime 运算,远快于 apply(lambda x: ...); 灵活可扩展 :只需修改频率字符串(如 '5T'、'H'、'D')即可适配不同粒度。 ⚠️ 注意事项 : strftime('%Y-%-m-%-d ...') 中的 %-m 在 Windows 系统可能报错,生产环境建议统一使用 %Y-%m-%d(补零格式),或先 .dt.strftime(...).str.replace(r'^0+', '', regex=True) 后处理; 若原始 ts 列含时区信息,floor() 会自动在本地时区计算,必要时先 .dt.tz_localize() 或 .dt.tz_convert() 统一时区; floor 与 round/ceil 行为不同:floor 严格向下(如 00:09:59 → 00:00:00),而 round('10min') 会四舍五入(00:09:59 → 00:10:00),请按业务语义选择。 掌握 dt.floor() 是 Pandas 时间特征工程的关键基础能力——它让时间对齐变得既精确又可控。

相关文章