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

基于空间位置(lon、lat)与datetime匹配近邻,为DataFrame补充温度数据

时空近邻匹配:为Dataset 1新增温度列的实现方案

需求概述

你需要基于优先空间近邻、再时间近邻的规则,从Dataset 2中为Dataset 1的每个采样点匹配对应的温度值:

  • Dataset 1:仅包含采样点的datetime、longitude、latitude
  • Dataset 2:包含大范围时空的温度数据,需筛选出与Dataset 1点最匹配的记录

解决方案(Python实现)

针对大型数据集,我们采用空间索引加速近邻查询+时间差筛选的组合方案,兼顾效率和准确性。

1. 数据预处理

首先确保两个数据集的时间格式为datetime,经纬度为数值类型:

import pandas as pd
from scipy.spatial import KDTree
import numpy as np

# 加载数据集(替换为你的实际数据路径)
df1 = pd.read_csv("dataset1.csv", parse_dates=["datetime"])
df2 = pd.read_csv("dataset2.csv", parse_dates=["datetime"])

# 确保经纬度是数值型
df1[["longitude", "latitude"]] = df1[["longitude", "latitude"]].astype(float)
df2[["longitude", "latitude"]] = df2[["longitude", "latitude"]].astype(float)

2. 构建空间索引(KDTree)

用KDTree对Dataset 2的经纬度构建空间索引,大幅提升大型数据集的近邻查询速度:

# 提取Dataset 2的经纬度坐标,转为数组格式
coords2 = df2[["longitude", "latitude"]].values
kdtree = KDTree(coords2)

3. 时空近邻匹配逻辑

对Dataset 1的每个点,先查询空间最近的N个候选点(N可根据数据密度调整,这里设为5),再在候选点中筛选时间最近的记录,提取温度值:

def match_temp(row):
    # 当前点的经纬度和时间
    lon, lat = row["longitude"], row["latitude"]
    dt = row["datetime"]
    
    # 1. 查询空间最近的5个候选点(返回距离和索引)
    distances, indices = kdtree.query([[lon, lat]], k=5)
    candidates = df2.iloc[indices[0]]
    
    # 2. 计算候选点与当前点的时间差绝对值
    candidates["time_diff"] = abs(candidates["datetime"] - dt)
    
    # 3. 找到时间差最小的候选点,返回对应的温度
    closest_candidate = candidates.sort_values("time_diff").iloc[0]
    return closest_candidate["temp"]

# 为Dataset 1新增temp列
df1["temp"] = df1.apply(match_temp, axis=1)

4. 结果验证

运行后你将得到符合预期的结果:

datetime longitude latitude  temp
0 2022-08-10 03:26:08  147.8521 -20.2443  21.49
1 2020-10-02 16:12:52  152.3652 -23.1234  20.80

优化说明

  • 如果Dataset 2数据量极大,可调整k值(候选点数量)平衡速度和准确性;
  • 若空间精度要求高,可改用Haversine公式计算实际球面距离(替代KDTree的欧氏距离),适合经纬度地理数据:
    def haversine(lon1, lat1, lon2, lat2):
        lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
        dlon = lon2 - lon1
        dlat = lat2 - lat1
        a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
        c = 2 * np.arcsin(np.sqrt(a))
        r = 6371  # 地球半径(公里)
        return c * r
    
    此时需遍历计算距离,但可通过分批处理优化效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:33:28