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

Pandas中基于另一DataFrame最近时间戳匹配并赋值数据列

解决Pandas中按最近时间戳匹配数据列的报错问题

问题背景

有两个按时间排序的Pandas DataFrame(df1和df2),均包含时间戳列与数据列。需求为:针对df1中的每个时间戳,找到df2中时间戳最接近的行,并将该行的Data2值赋值给df1对应行。

已通过get_indexer获取到正确的索引位置及对应时间戳值,但执行最后一段代码时出现错误:

ValueError: cannot reindex from a duplicate axis

用户提供的完整代码及运行输出如下:

import pandas as pd

df1 = pd.DataFrame({'Time1': ['2023-11-30 13:01:51.813', 
                              '2023-11-28 10:01:51.760', 
                              '2023-11-28 10:01:51.347', 
                              '2023-11-27 10:01:51.320', 
                              '2023-11-26 10:01:51.260'], 
                    'Data1': [2, 4, 6, 8, 10]})

df2 = pd.DataFrame({'Time2': ['2023-11-30 10:00:03.733', 
                              '2023-11-29 08:00:03.767', 
                              '2023-11-28 16:00:03.523', 
                              '2023-11-27 14:00:03.827', 
                              '2023-11-26 12:00:03.417'], 
                    'Data2': ['A', 'B', 'C', 'D', 'E']})

# 格式化时间为datetime类型
df1['Time1'] = pd.to_datetime(df1['Time1'], format='%Y-%m-%d %H:%M:%S.%f')
df2['Time2'] = pd.to_datetime(df2['Time2'], format='%Y-%m-%d %H:%M:%S.%f')

# 将Time2设为df2的索引
df2 = df2.set_index('Time2')

# 为每个Time1找到最接近的Time2的位置索引
df1['Data2Index']= df2.index.get_indexer(df1['Time1'], method='nearest')

# 为每个Time1找到最接近的Time2的索引值
df1['Data2Time'] = df2.index[df2.index.get_indexer(df1['Time1'], method='nearest')]

print(df1)
print(df2)

# 运行输出
#                     Time1  Data1  Data2Index               Data2Time
# 0 2023-11-30 13:01:51.813      2           0 2023-11-30 10:00:03.733
# 1 2023-11-28 10:01:51.760      4           2 2023-11-28 16:00:03.523
# 2 2023-11-28 10:01:51.347      6           2 2023-11-28 16:00:03.523
# 3 2023-11-27 10:01:51.320      8           3 2023-11-27 14:00:03.827
# 4 2023-11-26 10:01:51.260     10           4 2023-11-26 12:00:03.417
#                         Data2
# Time2
# 2023-11-30 10:00:03.733     A
# 2023-11-29 08:00:03.767     B
# 2023-11-28 16:00:03.523     C
# 2023-11-27 14:00:03.827     D
# 2023-11-26 12:00:03.417     E

# 尝试获取对应Data2值(执行报错)
df1['Data2']= df2.Data2[df2.index.get_indexer(df1['Time1'], method='nearest')]

错误原因

报错核心在于:df2.Data2[索引数组]返回的Series保留了df2的原时间戳索引,而df1使用默认整数索引(0-4),两者索引体系不匹配。同时df1中存在重复的匹配位置(比如第1、2行都匹配到df2的位置2),导致Pandas无法完成索引对齐,从而抛出重复轴错误。

解决方案

方案1:利用已计算的Data2Index直接取值

既然已经在df1中存储了Data2Index(匹配到的df2行的位置索引),直接用.iloc按位置提取值,并转为numpy数组避免索引对齐问题:

df1['Data2'] = df2['Data2'].iloc[df1['Data2Index']].values

方案2:一步到位提取值

不需要重复计算索引,直接获取匹配位置后提取Data2值:

# 替换报错的最后一行代码
match_indices = df2.index.get_indexer(df1['Time1'], method='nearest')
df1['Data2'] = df2['Data2'].iloc[match_indices].values

方案3:使用merge_asof(推荐)

Pandas内置的merge_asof专门用于按最近时间戳合并DataFrame,代码更简洁高效,无需手动处理索引:

# 确保两个DataFrame按时间排序(题目已说明排序,可再次确认)
df1 = df1.sort_values('Time1')
df2 = df2.reset_index().sort_values('Time2')

# 按最近时间合并,direction='nearest'表示匹配最近的时间戳
merged_df = pd.merge_asof(df1, df2, left_on='Time1', right_on='Time2', direction='nearest')
# 整理需要的列
merged_df = merged_df[['Time1', 'Data1', 'Data2', 'Time2']].rename(columns={'Time2': 'Data2Time'})

最终效果

执行任意方案后,df1会得到正确的Data2值:

Time1  Data1  Data2Index               Data2Time Data2
0 2023-11-30 13:01:51.813      2           0 2023-11-30 10:00:03.733     A
1 2023-11-28 10:01:51.760      4           2 2023-11-28 16:00:03.523     C
2 2023-11-28 10:01:51.347      6           2 2023-11-28 16:00:03.523     C
3 2023-11-27 10:01:51.320      8           3 2023-11-27 14:00:03.827     D
4 2023-11-26 10:01:51.260     10           4 2023-11-26 12:00:03.417     E

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:44:55