
本文介绍使用 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 时间特征工程的关键基础能力——它让时间对齐变得既精确又可控。










