基于不规则时间戳的DataFrame近邻匹配合并方法求助
按最接近时间戳合并两个采样频率不同的DataFrame
我有两个包含时间戳和测量值的DataFrame,分别对应测量值X和Y。需要基于时间索引合并两者以对比数据,但它们的时间戳不完全一致,且X的采样频率高于Y。要求将每个Y值匹配到时间戳最接近的X行,其余X行直接丢弃。
示例数据
import pandas as pd from datetime import datetime x = pd.DataFrame([[datetime(year=2022, month=9, day=6, hour=13, minute=13, second=13), 4], [datetime(year=2022, month=9, day=6, hour=13, minute=15, second=24), 3], [datetime(year=2022, month=9, day=6, hour=13, minute=18, second=36), 2], [datetime(year=2022, month=9, day=6, hour=13, minute=21, second=56), 1]], columns=['time', 'x']) y = pd.DataFrame([[datetime(year=2022, month=9, day=6, hour=13, minute=13, second=59), 14], [datetime(year=2022, month=9, day=6, hour=13, minute=19, second=10), 13]], columns=['time', 'y'])
期望合并结果
joined = pd.DataFrame([[datetime(year=2022, month=9, day=6, hour=13, minute=13, second=13), datetime(year=2022, month=9, day=6, hour=13, minute=13, second=59), 4, 14], [datetime(year=2022, month=9, day=6, hour=13, minute=18, second=36), datetime(year=2022, month=9, day=6, hour=13, minute=19, second=10), 2, 13]], columns=['time_x', 'time_y', 'x', 'y'])
解决方案
方法1:使用merge_asof(推荐)
pandas.merge_asof专门用于按最近的键合并两个有序的DataFrame,非常适合时间序列的匹配场景。
# 按时间列排序(merge_asof要求输入DataFrame必须按合并键排序) x_sorted = x.sort_values('time') y_sorted = y.sort_values('time') # 按最近时间戳合并,direction='nearest'表示匹配最接近的时间点 merged = pd.merge_asof(y_sorted, x_sorted, on='time', direction='nearest') # 重命名列并调整顺序,对齐期望结果 result = merged.rename(columns={'time': 'time_y', 'time_x': 'time'}).reindex(columns=['time', 'time_y', 'x', 'y']) result = result.rename(columns={'time': 'time_x'}) print(result)
方法2:手动匹配最近索引
通过将X的时间列转为DatetimeIndex,利用get_indexer方法找到每个Y时间戳对应的X中最近的行索引,再手动合并。
# 将X的时间列设为索引 x_indexed = x.set_index('time') # 为每个Y的时间戳找到X中最接近的索引位置 match_indices = x_indexed.index.get_indexer(y['time'], method='nearest') # 提取匹配的X行,与Y合并 x_matched = x.iloc[match_indices].reset_index(drop=False) result = pd.concat([x_matched, y.reset_index(drop=True)], axis=1) # 调整列名和顺序 result.columns = ['time_x', 'x', 'time_y', 'y'] result = result[['time_x', 'time_y', 'x', 'y']] print(result)
两种方法都能得到与期望一致的结果,其中merge_asof性能更优,适合处理大规模时间序列数据;手动匹配的方式更直观,便于自定义调整匹配逻辑。
内容的提问来源于stack exchange,提问作者Bas R
相关产品推荐
相关产品推荐

