【问题标题】:How do I calculate the closest element in another list for all of my list? [duplicate]如何为我的所有列表计算另一个列表中最接近的元素? [复制]
【发布时间】:2020-05-14 08:05:27
【问题描述】:

我有两个“顶点”数组(x、y、z 位置):

vert_list_1 = [[1.2, 3.4, 5.6]...[-5.2,-6.0,2.9]]
vert_list_2 = [[10.0, 9.1, 2.7]...[117.0, 1.1, 2.8]]

列表有不同的长度。

我希望找到一个列表最接近的_vert_2_index,这样

np.linalg.norm(vert_list_2[closest_vert_2_index[i]] - vert_list_1[i])

被最小化了。

closest_vert_2_index 可以包含重复项(谢天谢地,否则这是一个更难的问题!)

天真地我会这样做

closest_vert_2_index = []

for vert in vert_list_1:
   best_dist = None
   best_vert_2_id = None

   for i, vert_2 in enumerate(vert_2_list):
      dist = np.linalg.norm(vert_2 - vert)
      if best_dist is None or dist < best_dist:
         best_dist = dist
         best_vert_2_id = i

   closest_vert_2_index.append(best_vert_2_id)

但我想知道是否有人可以更快地想到任何事情。

【问题讨论】:

  • 我不确定您为什么要使用lists,因为即使您的幼稚方法也行不通(vert_2 - vert 将失败,因为- 未在列表中定义)。
  • @divakar 相关问题是相关的,但是建议的副本没有处理一个额外的循环。
  • @norok2 我在那里看不到循环。而Kdtree 应该就足够了。
  • @Divakar 查看两个问题中的 OP 代码,另一个有一个循环,这个有两个循环。输入也不同。可能是kdtree有用,但是这两个问题问的不是同一个问题。
  • @norok2 对于重复项,我想我们看看答案。假设数组输入(我认为这是安全的,因为发布的代码似乎假设相同),使用 ckDtree 在那里接受的一个非常有效地解决了它,同样在这里没有任何更改。这两个本质上是在问同一个问题,只是用了不同的词。

标签: python numpy


【解决方案1】:

将您的列表转换为 numpy 数组,您可以这样做。这相当快:

import numpy as np

vert_list_1 = np.array(vert_list_1)
vert_list_2 = np.array(vert_list_2)
closest_vert_2_index = np.argmin(np.linalg.norm(vert_list_2[:,None] - vert_list_1, axis=-1)

获取每对行的差异,找到它的范数并获得每行的最小值索引。

另一种方法是使用KDTree和查询:

from scipy.spatial import cKDTree

vert_list_1 = np.array(vert_list_1)
vert_list_2 = np.array(vert_list_2)
tree = cKDTree(vert_list_2)
dist, closest_vert_2_index = tree.query(vert_list_1, k=1)

【讨论】:

  • 这很好,谢谢 - 但不幸的是我的列表有 200k 长,这种方法需要 200kx200kx3 分配,这是一个内存问题。
  • @omroth 也许你应该先构建一个 NumPy 数组而不是 list
  • @Omroth 在这种情况下你应该使用 KDTree。我更新了帖子。问题已结束。请接受答案,以便其他人发现它有帮助。谢谢。
【解决方案2】:

当您正在计算两个“顶点”* 之间的距离并期望出现重复项时,请考虑使用 functools.lru_cache 装饰器。要使用它,您需要编写函数 - 在您的情况下,它将类似于 calculate_dist(vertex1, vertex2)。使用lru_cache修饰后,结果不仅会返回,还会存储,所以下次调用相同参数时,会从存储中检索而不是计算。

*计算距离可以通过所谓的pure函数来完成,即输出完全取决于输入。 functools.lru_cache 设计用于纯函数。

【讨论】:

    猜你喜欢
    • 2018-01-11
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多