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

基于相近时间合并DataFrame(类Excel VLOOKUP)失败求替代方案

按相近时间合并DataFrame的解决方案

一、修正你原本的merge_asof方法

你之前用merge_asof失败,通常是两个核心问题:时间列不是datetime类型,或者右侧数据集的时间列未排序。按下面步骤修正即可:

代码示例

import pandas as pd

path = r"C:\Users\Documents\"
df1 = pd.read_csv(path + '\obs_heads.csv')
df2 = pd.read_csv(path + '\sim.csv')

# 1. 将时间列转为pandas可识别的datetime类型
df1['A2'] = pd.to_datetime(df1['A2'])
df2['A2'] = pd.to_datetime(df2['A2'])

# 2. 对df2的时间列排序(merge_asof要求右侧数据集的匹配列必须有序)
df2 = df2.sort_values('A2').reset_index(drop=True)

# 3. 执行匹配:direction参数控制匹配规则
# - 'backward':找小于等于当前时间的最近值(类似VLOOKUP近似匹配)
# - 'nearest':找时间差最小的绝对最近值
t = pd.merge_asof(df1, df2, on="A2", direction='nearest')
print(t)

二、小数据集替代方案:逐行匹配最近时间

如果数据量不大,用apply逐行查找逻辑更直观:

代码示例

import pandas as pd

path = r"C:\Users\Documents\"
df1 = pd.read_csv(path + '\obs_heads.csv')
df2 = pd.read_csv(path + '\sim.csv')

# 转换时间列格式
df1['A2'] = pd.to_datetime(df1['A2'])
df2['A2'] = pd.to_datetime(df2['A2'])

# 定义函数,为df1的每一行找到df2中时间最近的行
def get_nearest_row(row):
    time_diff = abs(df2['A2'] - row['A2'])
    nearest_idx = time_diff.idxmin()
    return df2.loc[nearest_idx]

# 合并结果
result = df1.merge(
    df1.apply(get_nearest_row, axis=1),
    left_index=True, right_index=True,
    suffixes=('_obs', '_sim')  # 区分两个表的同名字段
)
print(result)

三、大数据集高效方案:KDTree快速匹配

如果数据量很大(十万条以上),用KDTree的空间索引可以大幅提升匹配速度:

代码示例

import pandas as pd
from scipy.spatial import KDTree

path = r"C:\Users\Documents\"
df1 = pd.read_csv(path + '\obs_heads.csv')
df2 = pd.read_csv(path + '\sim.csv')

# 将时间转为 Unix 时间戳(数值型,方便KDTree计算距离)
df1['A2_ts'] = pd.to_datetime(df1['A2']).astype('int64') // 10**9
df2['A2_ts'] = pd.to_datetime(df2['A2']).astype('int64') // 10**9

# 构建KDTree索引
tree = KDTree(df2[['A2_ts']])

# 为df1的每个时间点查找最近邻居
_, nearest_indices = tree.query(df1[['A2_ts']], k=1)

# 合并结果并清理临时列
result = df1.join(df2.iloc[nearest_indices].reset_index(drop=True), lsuffix='_obs', rsuffix='_sim')
result = result.drop(columns=['A2_ts_obs', 'A2_ts_sim'])
print(result)

补充说明你的数据情况

从你提供的输入来看:

  • df1(观测数据):包含索引列A1、时间列A2、数值列A3
  • df2(模拟数据):包含时间列A2、数值列B1、B2
  • 期望输出:以df1的行结构为基准,匹配df2中时间最接近的行,合并所有字段

以上三种方法都能实现这个需求,根据数据量选择即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:35:25