You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas合并DataFrame报错:ValueError: cannot reindex from a duplicate axis

问题描述

我拥有两个以时间戳datetime为索引的Pandas DataFrame,分别包含浮点类型列metric1和metric2。尝试合并这两个DataFrame时,出现如下错误:

ValueError: cannot reindex from a duplicate axis

查阅资料后仍未找到解决方案。尝试复现问题,但仅能通过特定数据触发,数据量过大无法完整上传。最终发现部分数据子集存在兼容性问题,部分则可正常合并。

期望合并后的结果索引包含所有时间戳,同时保留metric1和metric2列,无对应数据的位置填充NaN。通常pd.concat可实现此需求,但本次合并tt1与tt2时报错,合并tt1与tt4则正常。


复现文件与代码

CSV文件

test1.csv
timestamp,metric1
2018-03-21 15:46:36,3.5555559999999997
2018-03-21 15:47:36,5.345001
2018-03-21 15:48:36,5.719998
test2.csv
timestamp,metric2
2018-03-28 05:49:59,3.28
2018-03-28 05:50:59,3.45
2018-03-28 05:51:59,3.258332
2018-03-28 05:52:59,3.068333
2018-03-28 05:53:59,2.9733330000000002
2018-03-28 05:54:59,3.0650009999999996
2018-03-28 05:55:59,3.109999
2018-03-28 05:56:59,3.3683330000000002
2018-03-28 05:57:59,3.1516669999999998
2018-03-28 05:58:59,3.051666
2018-03-28 05:59:59,3.3083339999999994
2018-03-28 06:01:01,3.328333
2018-03-28 06:01:01,3.1
2018-03-28 06:02:00,3.305
2018-03-28 06:03:00,3.29
2018-03-28 06:04:00,3.2183330000000003
2018-03-28 06:05:00,3.176666
2018-03-28 06:06:00,3.353333
2018-03-28 06:07:00,3.3233330000000003
2018-03-28 06:08:00,3.393332
2018-03-28 06:09:00,3.053334
2018-03-28 06:10:00,3.268333
2018-03-28 06:11:00,3.239999
2018-03-28 06:12:00,3.223332
2018-03-28 06:13:00,3.119999
test4.csv
timestamp,metric2
2018-03-21 00:00:00,10.665
2018-03-21 00:01:00,10.285
2018-03-21 00:02:00,10.12834

说明:test2.csv与test4.csv源自同一数据集

加载CSV的代码

import pandas as pd

tt1 = pd.read_csv('test1.csv', index_col=0)
tt1.index = pd.to_datetime(tt1.index)
tt2 = pd.read_csv('test2.csv', index_col=0)
tt2.index = pd.to_datetime(tt2.index)
tt4 = pd.read_csv('test4.csv', index_col=0)
tt4.index = pd.to_datetime(tt4.index)

合并测试

  • 无报错测试:
    tt3 = pd.concat([tt1, tt4], axis = 1)
    
  • 报错测试:
    tt3 = pd.concat([tt1, tt2], axis = 1)
    # 报错:ValueError: cannot reindex from a duplicate axis
    

解决方案

问题根源

一眼就能看出问题:test2.csv里存在重复的时间戳——2018-03-28 06:01:01对应两条不同的metric2记录。当使用pd.concat(axis=1)合并时,Pandas要求参与合并的DataFrame索引必须唯一,否则无法完成索引对齐的重索引操作,直接抛出错误。而test4.csv的索引没有重复,所以合并tt1和tt4完全正常。

你可以用以下代码验证索引重复情况:

# 检查tt2是否有重复索引
print("tt2索引是否有重复:", tt2.index.duplicated().any())
# 查看重复的索引值
print("重复的索引:", tt2.index[tt2.index.duplicated()])

针对需求的解决办法

你的需求是保留所有时间戳、无数据填充NaN,下面提供两种适配不同场景的方案:

方案1:保留重复索引的所有数据

如果这些重复时间戳的记录是合法的(比如同一时间点有多个观测值),可以用DataFrame.join()替代pd.concat,join默认支持重复索引的合并:

tt3 = tt1.join(tt2, how='outer')

合并后,重复的时间戳会保留所有行,metric1对应位置自动填充NaN(因为tt1没有该时间戳的数据)。

方案2:清理重复索引(保留唯一时间戳)

如果重复的时间戳是数据错误,先清理tt2的重复索引再合并:

  • 方式A:保留每个重复时间戳的第一条记录
    tt2_clean = tt2[~tt2.index.duplicated()]
    tt3 = pd.concat([tt1, tt2_clean], axis=1)
    
  • 方式B:保留每个重复时间戳的最后一条记录
    tt2_clean = tt2[~tt2.index.duplicated(keep='last')]
    tt3 = pd.concat([tt1, tt2_clean], axis=1)
    
  • 方式C:对重复时间戳的metric2值做聚合(比如取均值)
    tt2_clean = tt2.groupby(tt2.index).mean()
    tt3 = pd.concat([tt1, tt2_clean], axis=1)
    

验证结果

无论使用哪种方案,最终的tt3都会包含tt1和tt2的所有时间戳,无对应数据的位置自动填充NaN,完全符合你的预期需求。


内容的提问来源于stack exchange,提问作者ojunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:02:45