如何根据从一个数据帧到另一个数据帧的2个键找到最接近的匹配?

sok*_*014 6 python dataframe pandas

我有两个我正在使用的数据帧.一个有一堆位置和坐标(经度,纬度).另一个是天气数据集,其中包含来自世界各地气象站的数据及其各自的坐标.我正在尝试将最近的气象站连接到我的数据集中的每个位置.气象站名称和我的位置名称不匹配.

我试图通过坐标中最接近的匹配来链接它们,并且不知道从哪里开始.

我在考虑使用

np.abs((location['latitude']-weather['latitude'])+(location['longitude']-weather['longitude'])

各自的例子

地点...

Location   Latitude   Longitude Component  \
     A  39.463744  -76.119411    Active   
     B  39.029252  -76.964251    Active   
     C  33.626946  -85.969576    Active   
     D  49.286337   10.567013    Active   
     E  37.071777  -76.360785    Active   
Run Code Online (Sandbox Code Playgroud)

天气...

     Station Code             Station Name  Latitude  Longitude
     US1FLSL0019    PORT ST. LUCIE 4.0 NE   27.3237   -80.3111
     US1TXTV0133            LAKEWAY 2.8 W   30.3597   -98.0252
     USC00178998                  WALTHAM   44.6917   -68.3475
     USC00178998                  WALTHAM   44.6917   -68.3475
     USC00178998                  WALTHAM   44.6917   -68.3475
Run Code Online (Sandbox Code Playgroud)

输出将是位置数据帧上的新列,其中站名是最接近的匹配

但是我不知道如何通过两者来循环来实现这一目标.任何帮助将不胜感激..

谢谢,斯科特

Ian*_*anS 6

假设你有一个dist你想要最小化的距离函数:

def dist(lat1, long1, lat2, long2):
    return np.abs((lat1-lat2)+(long1-long2))
Run Code Online (Sandbox Code Playgroud)

对于给定的位置,您可以找到最近的车站,如下所示:

lat = 39.463744
long = -76.119411
weather.apply(
    lambda row: dist(lat, long, row['Latitude'], row['Longitude']), 
    axis=1)
Run Code Online (Sandbox Code Playgroud)

这将计算到所有气象站的距离.使用idxmin您可以找到最近的站名:

distances = weather.apply(
    lambda row: dist(lat, long, row['Latitude'], row['Longitude']), 
    axis=1)
weather.loc[distances.idxmin(), 'StationName']
Run Code Online (Sandbox Code Playgroud)

让我们将所有这些放在一个函数中:

def find_station(lat, long):
    distances = weather.apply(
        lambda row: dist(lat, long, row['Latitude'], row['Longitude']), 
        axis=1)
    return weather.loc[distances.idxmin(), 'StationName']
Run Code Online (Sandbox Code Playgroud)

您现在可以通过将其应用于locations数据帧来获取所有最近的站点:

locations.apply(
    lambda row: find_station(row['Latitude'], row['Longitude']), 
    axis=1)
Run Code Online (Sandbox Code Playgroud)

输出:

0         WALTHAM
1         WALTHAM
2    PORTST.LUCIE
3         WALTHAM
4    PORTST.LUCIE
Run Code Online (Sandbox Code Playgroud)

  • 对于最小距离,在两点lat/lon之间,应该是`sqrt((x1-x2)^ 2 +(y1-y2)^ 2)`.这仍然是考虑一个平面,更具体地说是球体,应该是一些不同的公式. (2认同)