【问题标题】:How can I optimize the distance between 2 points (x,y,z) and two arrays如何优化 2 个点 (x,y,z) 和两个数组之间的距离
【发布时间】:2020-04-14 04:18:52
【问题描述】:

我需要计算每个像素和每个质心之间的距离。

参数:

  • X(numpy 数组):PxD 第一组数据点(通常是数据点)
  • C(numpy 数组):KxD 第二组数据点(通常是聚类质心点)

返回:

  • dist:PxK numpy 数组位置 ij 是第一个集合的第 i 个点与第二个集合的第 j 个点之间的距离
def distance(X, C):

    dist = numpy.empty((X.shape[0], C.shape[0]))

    for i,x in enumerate(X):
        for y,c in enumerate(C):
            dist[i][y] = euclidean_dist(x,c)

    return dist

def euclidean_dist(x, y):
    x1, y1, z1 = x
    x2, y2, z2 = y
    return math.sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)

【问题讨论】:

  • 您有错误吗?你的代码有什么问题?不应该是dist[i,y]吗?
  • 不,没有错误。我怎样才能更快地使用矩阵 / 数组 / numpy 来处理它。

标签: python arrays numpy optimization


【解决方案1】:

如果你可以添加 scipy 依赖,那么这已经在scipy.spatial.distance.cdist 中实现了。否则我们可以使用numpy.broadcastingnumpy.linalg.norm

Scipy 实现

from scipy.spatial import distance
distance.cdist(X, C, 'euclidean')

Numpy 实现

import numpy as np
np.linalg.norm(X[:,None,:] - C, axis=2)

性能

P = 100_000
K = 10_00
D = 3

X = np.random.randint(0,10, (P,D))
C = np.random.randint(0,10, (K,D))

%timeit distance.cdist(X, C, 'euclidean')
1.06 s ± 57 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit np.linalg.norm(X[:,None,:] - C, axis=2)
15 s ± 2.18 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

我们可以看到,对于大尺寸的 XC,scipy 实现要快得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-19
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多