【问题标题】:Pythonic way to get closest point for each point in a data frame (Nearest Neighbour)获取数据框中每个点的最近点的 Pythonic 方法(最近邻)
【发布时间】:2014-03-16 17:57:19
【问题描述】:

我有一个位置和塔的列表。我试图找出每个位置最近的塔是什么。我想出了一种可行的方法,但我很确定这是一种非常低效的方法。

我将如何以更 Pythonic 的方式做到这一点?

我有大约 4,000 个地点和 11,000 座塔。我目前:

  1. 循环遍历每个位置
  2. 查找到所有塔的距离
  3. 按距离排序
  4. 取最近的一个,然后将其附加到“nearest_tower”数据框。

代码如下:

nearest_tower = pd.DataFrame()

for i, location_rows in d[["Name", "Lat", "Long"]].T.iteritems():
    tower_coords["Distance_km"] =  tower_coords.apply(lambda row: distance_on_unit_sphere(location_rows ["Lat"], location_rows ["Long"], row['DIGITAL_LATITUDE'], row['DIGITAL_LONGITUDE'])*6373, axis=1)
    a = tower_coords.sort(['Distance_km'], ascending = 1)[:1][["SITE_NUMBER", "DIGITAL_LATITUDE", "DIGITAL_LONGITUDE", "Distance_km"]]
    a["Location_Name"] = location_rows ["Name"]
    a["Location_Lat"] = location_rows ["Lat"]
    a["Location_Long"] = location_rows ["Long"]
    nearest_tower = nearest_tower.append(a)
    print(i)

Tower_coords 如下所示:

SITE_NUMBER    DIGITAL_LATITUDE      DIGITAL_LONGITUDE
1                67.21                     -30.432
...

【问题讨论】:

  • 什么是 tower_coords?那是什么样子的?
  • 如果将与本地塔的距离放在一起,那么您可以简单地从最近的塔上弹出。但可能还有更有效的数据结构来解决这个问题,比如@Hbcdev 提到的 k-d 树
  • @usethedeathstar 添加的文件示例,它只显示了一个塔的经纬度
  • 没有考虑距离的数字高度?你如何计算距离?我猜不是ECEF坐标? distance_on_unit_sphere 是如何工作的,它是从哪里来的?
  • 我使用了这个页面上的函数johndcook.com/python_longitude_latitude.html - 我收集的粗略计算,假设是球形奶牛。

标签: python loops pandas nearest-neighbor


【解决方案1】:

编辑:有人在这里解释了 Pandas 中的how to do a k-d tree search

Here is a solution 在另一个问题中利用了复杂数据类型(Python 和 Numpy 中的内置),它比循环更快,但使用大量内存。

Pandas Github proposing a get_nearest method 中存在一个问题,它会像 @Hbcdev 提到的那样进行 k-d 树搜索。 我自己正在尝试弄清楚如何在 Pandas 中实现 kNN 搜索。

【讨论】:

    【解决方案2】:

    首先,使用min (Python doc here) 找到最近的。您可以在可迭代对象之后提供 key 参数(这将是您的 lambda 函数)。

    使用类而不是类似 Hash 的结构而不是 a 对象会更符合 Python 风格。像 PyPy 这样的实现在处理类属性访问时会比处理类似哈希的访问更有效。

    整个函数可以做成map操作。您正在使用一个结构并将其映射到另一个结构,其中元素之间存在 1-1 对应关系,这使得它成为 map

    最后(这与 Pythonic 无关,但它很重要),您应该使用k-d tree 结构来有效地找到最近的点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 2021-07-14
      • 2020-10-30
      • 2013-06-06
      • 1970-01-01
      相关资源
      最近更新 更多