重叠时间索引需明确处理策略:concat后用sort_index对齐,再依需groupby聚合(如mean/last);combine_first仅单向填充空值,update可覆盖但不添加新索引,重采样前须先归一化索引。

用 pd.concat() + sort_index() 处理重叠时间索引
重叠索引不是错误,而是常见现象——比如两个传感器在相同时间点都采集了数据。Pandas 默认会保留所有行,不自动去重或覆盖,所以直接 concat 会导致重复时间戳。关键不是“避免重叠”,而是明确你要怎么处理它:concat 后必须决定是保留全部、取最后值、还是按规则合并。
- 用
pd.concat([ts1, ts2], axis=0)垂直拼接,保留所有原始行(包括重复时间戳) - 紧接着调用
.sort_index(),让时间对齐便于后续操作 - 如果想按时间戳聚合(如多个观测取均值),接
.groupby(level=0).mean();若只留最新一条,用.groupby(level=0).last() - 注意:若索引含时区(如
datetime64[ns, UTC]),必须先统一时区,否则groupby会把相同时间但不同时区的视为不同索引
combine_first() 适合补空缺,不是合并冲突
很多人误以为 combine_first() 是“智能合并”,其实它只做单向填充:用右侧非空值填补左侧空缺,对重叠位置的非空值不做覆盖也不报错——左侧值永远优先。它不解决“两个都有值怎么办”的问题。
- 适用场景:一个序列是主数据(如每日收盘价),另一个是补充修正(如某日人工校准值),且你明确希望“主数据为主,仅缺值才用补充”
- 写法:
ts_main.combine_first(ts_correction),结果索引是二者并集,重叠处完全保留ts_main的值 - 陷阱:若两个序列在相同时间都有有效值,
combine_first不会警告、不提示冲突,静默丢弃右侧值——容易漏掉数据矛盾
用 update() 覆盖指定时间点,需谨慎控制范围
update() 是唯一真正“覆盖式合并”的方法,但它默认就地修改,且只更新左侧已存在的索引位置。如果你的修正数据包含新时间点,它们不会被加入结果中。
- 要让新时间点也进来,得先用
pd.concat(..., sort=False)拼出全量索引,再.update(),或改用reindex().update() - 安全做法:先检查重叠部分差异,比如
ts1.index.intersection(ts2.index),再决定是否允许覆盖 - 注意
update对 NaN 的处理:右侧为 NaN 时,不会覆盖左侧非空值——这点和combine_first相反
重采样前先对齐,否则 resample() 会放大重叠误差
如果最终目标是降频(如分钟→小时),别急着先 resample。重叠索引在重采样时会被分别计算,导致同一小时里出现多条“第一条记录”或“平均值被重复计入”。必须先归一化索引再重采样。
- 推荐流程:先
concat→sort_index→groupby(level=0).first()(或.mean())→ 再resample('H').mean() - 如果原始数据是不规则高频(如每秒多个点),建议用
.asfreq('S')或.reindex()插值对齐,而不是依赖resample自动处理重叠 - 性能提醒:对千万级时间点做
groupby可能慢,可先用.index.duplicated(keep='first')标记重复项,再布尔索引过滤
真正麻烦的从来不是怎么合并,而是没想清楚“重叠意味着什么”——是数据冗余?测量误差?还是业务上本该互斥?选函数只是执行决策,前提是你已经判断好哪个时间点的值更可信、要不要保留历史痕迹、以及下游系统能否接受非单调索引。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











