python - numpy 中两个列表的成对操作(距离)

标签 python numpy

我有两个坐标列表:

l1 = [[x,y,z],[x,y,z],[x,y,z],[x,y,z],[x,y,z]]
l2 = [[x,y,z],[x,y,z],[x,y,z]]

我想找到 l1 和 l2 之间的最短成对距离。两个坐标之间的距离很简单:

numpy.linalg.norm(l1_element - l2_element)

那么如何使用 numpy 有效地将此操作应用于每对元素?

最佳答案

这里是对目前提出的四种方法的快速性能分析:

import numpy
import scipy
from itertools import product
from scipy.spatial.distance import cdist
from scipy.spatial import cKDTree as KDTree

n = 100
l1 = numpy.random.randint(0, 100, size=(n,3))
l2 = numpy.random.randint(0, 100, size=(n,3))

# by @Phillip
def a(l1,l2):
    return min(numpy.linalg.norm(l1_element - l2_element) for l1_element,l2_element in product(l1,l2))

# by @Kasra
def b(l1,l2):
    return numpy.min(numpy.apply_along_axis(
        numpy.linalg.norm,
        2,
        l1[:, None, :] - l2[None, :, :]
    ))

# mine
def c(l1,l2):
    return numpy.min(scipy.spatial.distance.cdist(l1,l2))

# just checking that numpy.min is indeed faster.
def c2(l1,l2):
    return min(scipy.spatial.distance.cdist(l1,l2).reshape(-1))

# by @BrianLarsen
def d(l1,l2):
    # make KDTrees for both sets of points
    t1 = KDTree(l1)
    t2 = KDTree(l2)
    # we need a distance to not look beyond, if you have real knowledge use it, otherwise guess
    maxD = numpy.linalg.norm(l1[0] - l2[0]) # this could be closest but anyhting further is certainly not
    # get a sparce matrix of all the distances

    ans = t1.sparse_distance_matrix(t2, maxD)

    # get the minimum distance and points involved
    minD = min(ans.values())
    return minD

for x in (a,b,c,c2,d):
    print("Timing variant", x.__name__, ':', flush=True)
    print(x(l1,l2), flush=True)
    %timeit x(l1,l2)
    print(flush=True)

对于n=100

Timing variant a :
2.2360679775
10 loops, best of 3: 90.3 ms per loop

Timing variant b :
2.2360679775
10 loops, best of 3: 151 ms per loop

Timing variant c :
2.2360679775
10000 loops, best of 3: 136 µs per loop

Timing variant c2 :
2.2360679775
1000 loops, best of 3: 844 µs per loop

Timing variant d :
2.2360679775
100 loops, best of 3: 3.62 ms per loop

对于n=1000

Timing variant a :
0.0
1 loops, best of 3: 9.16 s per loop

Timing variant b :
0.0
1 loops, best of 3: 14.9 s per loop

Timing variant c :
0.0
100 loops, best of 3: 11 ms per loop

Timing variant c2 :
0.0
10 loops, best of 3: 80.3 ms per loop

Timing variant d :
0.0
1 loops, best of 3: 933 ms per loop

关于python - numpy 中两个列表的成对操作(距离),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29608987/

相关文章:

python - 模运算递归

python - 在 mac os 上为 python3 安装 mysqlclient for mariadb

python - 为什么Python会修改跳出循环的列表?

numpy - 类型错误 : ufunc 'subtract' did not contain a loop with signature matching types dtype ('<U1' ) dtype ('<U1' ) dtype ('<U1' )

python - 有效地找到多列的低中位数

python - SciPy 无法将复数转换为 float

python - Lists 列表和 "Too many values to unpack"

python - 为什么我的 Apache 看不到我的媒体文件夹?

在任意位置插入列的 Pythonic 方式

python - 如何将二维 NumPy 数组的相应值映射到一维数组