【问题标题】:How to find the closest match based on 2 keys from one dataframe to another?如何根据从一个数据帧到另一个数据帧的 2 个键找到最接近的匹配项?
【发布时间】:2016-04-25 23:17:58
【问题描述】:

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

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

我正在考虑使用

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   

天气...

     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

输出将是位置数据框上的一个新列,其中车站名称是最接近的匹配

但是我不确定如何循环通过两者来完成此操作。任何帮助将不胜感激..

谢谢, 斯科特

【问题讨论】:

  • 你能给出你的 2 个 data.frames 的样本和预期的输出吗?
  • 除非您特别想在 python 中执行此操作,否则您应该考虑使用 postGIS 查询,它们对于您的情况可能非常快。
  • 更新以反映每个数据帧的样本和所需的输出
  • @sokeefe1014 你试过geopandas 用于地理数据处理吗?

标签: python pandas dataframe


【解决方案1】:

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

def dist(lat1, long1, lat2, long2):
    return np.abs((lat1-lat2)+(long1-long2))

对于给定的位置,您可以通过以下方式找到最近的车站:

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

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

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

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

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']

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

locations.apply(
    lambda row: find_station(row['Latitude'], row['Longitude']), 
    axis=1)

输出:

0         WALTHAM
1         WALTHAM
2    PORTST.LUCIE
3         WALTHAM
4    PORTST.LUCIE

【讨论】:

  • 两点纬度/经度之间的最小距离,应该是sqrt((x1-x2)^2+(y1-y2)^2)。这仍然在考虑一个平面,更具体地说是在球体上,应该是一些不同的公式。
  • 欣赏答案!仍在最终确定以确保一切正常。我确实必须更新 dist 函数以在纬度计算周围有一个 np.abs ,然后再次在经度计算周围。有时,当纬度偏离正数,而经度偏离负数时,它们会抵消并给我一些甚至不接近的东西。除此之外,我相信它可以完美运行。然后我会将输出合并到索引上的位置数据框吗?
  • @sokeefe1014 将结果包含在原始数据框中的最佳方式可能类似于locations['closest_station'] = locations.apply(lambda row: ..., axis=1)
  • 非常感谢!
【解决方案2】:

所以我很欣赏这有点混乱,但我使用了类似的东西来匹配表之间的遗传数据。它依赖于位置文件的经度和纬度在天气文件的 5 以内,但如果需要可以更改。

rows=range(location.shape[0])
weath_rows = range(weather.shape[0])
for r in rows:
    lat = location.iloc[r,1]
    max_lat = lat +5
    min_lat = lat -5
    lon = location.iloc[r,2]
    max_lon = lon +5
    min_lon = lon -5
    for w in weath_rows:
        if (min_lat <= weather.iloc[w,2] <= max_lat) and (min_lon <= weather.iloc[w,3] <= max_lon):
            location['Station_Name'] = weather.iloc[w,1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2022-10-12
    • 2021-05-12
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多