【问题标题】:How can I speed up closest point comparison using cdist or tensorflow?如何使用 cdist 或 tensorflow 加快最近点比较?
【发布时间】:2018-09-14 19:31:15
【问题描述】:

我有两组点,一组是由 x,y 坐标组成的地图,第二组是由 x,y 坐标组成的路径。我试图找到离我的路径点最近的地图点,非常简单。除了我的地图有 380000 个点,而我的路径(我有几个)每个都由 ~ 350000 个点组成。 除了对我的数据进行采样以获得更小的数据集之外,我还试图找到一种更快的方法来完成这项任务。

基本算法:

import pandas as pd
from scipy.spatial.distance import cdist
...

def closeset_point(point, points):
    return points[cdist([point], points).argmin()]

# log['point'].shape; 333000
# map_data['point'].shape; 380000
closest = [closest_point(log_p, list(map_data['point'])) for log_p in log['point']]

按照这个例子:Find closest point in Pandas DataFrames

在将其转换为 tqdm 进度条以查看需要多长时间(显然需要一段时间)后,我注意到大约需要 10 小时才能完成。

tqdm 循环:

for i in trange(len(log), desc='finding closest points'):
    closest.append(closest_point(log['point'].loc[i], list(map_data['point'])))
>> finding closest points: 5%|   | 16432/333456 [32:11<10:13:52], 8.60it/s

虽然 10 小时并非不可能,但我想知道是否有办法加快速度?我有一个可靠的 gpu/cpu/ram 供我使用,所以我觉得这应该是可行的。我也在学习 tensorflow(但老实说我的数学很糟糕,所以我对它一无所知)

关于如何通过多线程、gpu 计算、张量流或其他某种魔法来加快速度的任何想法? inb4 python 很慢;)

*edit:图像显示了我正在尝试做的事情。绿色是路径,蓝色是地图,橙色是我要找到的。

【问题讨论】:

  • 所以你有一组固定的地图点,你想为每个路径点找到最近的地图点?您可能想研究一些专门用于解决最近邻搜索等问题的数据结构,例如 kd-tree。
  • 也许你可以展示一些地图坐标、一些路径坐标和一个小图表来突出你想要找到的东西。
  • 我设法将它缩短到大约 20 分钟。 cdist 的快速之处在于,如果您使用两个列表来执行此操作,因此我将路径分成 1000 个块并执行 cdist(path[x:x+1000], map) 并且速度非常快。

标签: python performance pandas tensorflow


【解决方案1】:

以下是您尝试执行的操作的一个小示例。将变量coords1 视为您的变量log['point'],将coords2 视为您的变量log['point']。最终结果是最接近coord1coord2 的索引。

from scipy.spatial import distance
import numpy as np
coords1 = [(35.0456, -85.2672),
          (35.1174, -89.9711),
          (35.9728, -83.9422),
          (36.1667, -86.7833)]
coords2 = [(35.0456, -85.2672),
          (35.1174, -89.9711),
          (35.9728, -83.9422),
          (34.9728, -83.9422),
          (36.1667, -86.7833)]


tmp = distance.cdist(coords1, coords2, "sqeuclidean") #  sqeuclidean based on Mark Setchell comment to improve speed further
result = np.argmin(tmp,1)
# result: array([0, 1, 2, 4])

这应该更快,因为它在一次迭代中完成了所有事情。

【讨论】:

  • 我不会说 Python,但你能不能改成distance.cdist(coords1,coords2,'sqeuclidean') 来避免可能很昂贵的平方根 - 因为如果a^2 b^2,那么a b(当ab 都已经是正方形,因此是正数时)。
  • 不错的评论。我会把它放在答案上。谢谢=)
  • 哇,好吧,所以我想办法自己制作列表格式,它从 10 小时缩短到 20 分钟,然后“sqeuclidean”选项进一步缩短到 12 分钟!谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-19
  • 2017-02-01
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
相关资源
最近更新 更多