当前位置: 首页 > 面试题库 >

数组中点之间的快速加权欧式距离

佴阳辉
2023-03-14
问题内容

我需要有效地计算给定数组中每个点到另一个数组中每个其他点的欧几里德 加权 距离。这是我拥有的代码,可以正常工作:x,y``x,y

import numpy as np
import random

def rand_data(integ):
    '''
    Function that generates 'integ' random values between [0.,1.)
    '''
    rand_dat = [random.random() for _ in range(integ)]

    return rand_dat

def weighted_dist(indx, x_coo, y_coo):
    '''
    Function that calculates *weighted* euclidean distances.
    '''
    dist_point_list = []
    # Iterate through every point in array_2.
    for indx2, x_coo2 in enumerate(array_2[0]):
        y_coo2 = array_2[1][indx2]
        # Weighted distance in x.
        x_dist_weight = (x_coo-x_coo2)/w_data[0][indx] 
        # Weighted distance in y.
        y_dist_weight = (y_coo-y_coo2)/w_data[1][indx] 
        # Weighted distance between point from array_1 passed and this point
        # from array_2.
        dist = np.sqrt(x_dist_weight**2 + y_dist_weight**2)
        # Append weighted distance value to list.
        dist_point_list.append(round(dist, 8))

    return dist_point_list


# Generate random x,y data points.
array_1 = np.array([rand_data(10), rand_data(10)], dtype=float)

# Generate weights for each x,y coord for points in array_1.
w_data = np.array([rand_data(10), rand_data(10)], dtype=float)

# Generate second larger array.
array_2 = np.array([rand_data(100), rand_data(100)], dtype=float)


# Obtain *weighted* distances for every point in array_1 to every point in array_2.
dist = []
# Iterate through every point in array_1.
for indx, x_coo in enumerate(array_1[0]):
    y_coo = array_1[1][indx]
    # Call function to get weighted distances for this point to every point in
    # array_2.
    dist.append(weighted_dist(indx, x_coo, y_coo))

最终列表dist包含的子列表数量与第一个数组中的点数量相同,每个元素中的元素数量与第二个数组中的点数量相同(加权距离)。

我想知道是否有一种方法可以提高此代码的效率,也许使用cdist函数,因为当数组中有很多元素(在我的情况下,它们具有)并且必须检查时,此过程会变得非常昂贵许多数组的距离(我也有)


问题答案:

@Evan和@Martinis Group处在正确的轨道上-
扩大Evan的答案,以下是一个函数,该函数使用广播快速计算n维加权欧式距离,而无需Python循环:

import numpy as np

def fast_wdist(A, B, W):
    """
    Compute the weighted euclidean distance between two arrays of points:

    D{i,j} = 
    sqrt( ((A{0,i}-B{0,j})/W{0,i})^2 + ... + ((A{k,i}-B{k,j})/W{k,i})^2 )

    inputs:
        A is an (k, m) array of coordinates
        B is an (k, n) array of coordinates
        W is an (k, m) array of weights

    returns:
        D is an (m, n) array of weighted euclidean distances
    """

    # compute the differences and apply the weights in one go using
    # broadcasting jujitsu. the result is (n, k, m)
    wdiff = (A[np.newaxis,...] - B[np.newaxis,...].T) / W[np.newaxis,...]

    # square and sum over the second axis, take the sqrt and transpose. the
    # result is an (m, n) array of weighted euclidean distances
    D = np.sqrt((wdiff*wdiff).sum(1)).T

    return D

为了检查是否可以正常工作,我们将其与使用嵌套Python循环的较慢版本进行比较:

def slow_wdist(A, B, W):

    k,m = A.shape
    _,n = B.shape
    D = np.zeros((m, n))

    for ii in xrange(m):
        for jj in xrange(n):
            wdiff = (A[:,ii] - B[:,jj]) / W[:,ii]
            D[ii,jj] = np.sqrt((wdiff**2).sum())
    return D

首先,让我们确保两个函数给出相同的答案:

# make some random points and weights
def setup(k=2, m=100, n=300):
    return np.random.randn(k,m), np.random.randn(k,n),np.random.randn(k,m)

a, b, w = setup()
d0 = slow_wdist(a, b, w)
d1 = fast_wdist(a, b, w)

print np.allclose(d0, d1)
# True

不用说,使用广播而不是Python循环的版本要快几个数量级:

%%timeit a, b, w = setup()
slow_wdist(a, b, w)
# 1 loops, best of 3: 647 ms per loop

%%timeit a, b, w = setup()
fast_wdist(a, b, w)
# 1000 loops, best of 3: 620 us per loop


 类似资料:
  • 返回两点之间的欧氏距离。 使用 Math.hypot() 计算两点之间的欧氏距离( Euclidean distance)。 const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); distance(1, 1, 2, 3); // 2.23606797749979

  • 我在一个列表中有8个点,我需要计算所有可能对之间的欧几里德距离。我可以编写一个for循环并继续计算距离,但是python/numpy/others有更好的方法吗? 坐标点:

  • 我想写一个函数来计算中的坐标与中的每个坐标之间的欧氏距离,并通过列生成维度行的距离数组(其中是中的坐标数,是中的坐标数)。 NB:为了简单起见,我不想使用任何其他库。 运行该函数将生成: 我一直在试着运行下面的程序 但我得到以下错误: 非常感谢。

  • > 将图像重塑为一对列向量和行向量: 计算度量矩阵G,其条目由公式给出 其中,r是一个从0到20变化的全局参数,d是像素i和像素j之间的距离。E、 例如,如果像素i是(k,l),像素j是(k1,l1),则d=sqrt((k-k1)^2(l-l1)^2) 。像素1将是(1,1),像素2将是(1,2),依此类推。因此,矩阵G的大小将为1638400×1638400。 计算两个图像之间的最终(标量)欧几

  • 假设我有一个有两列X和Y的表T,我想找到所有的元组对,其中使用每个元组X和Y计算它们的欧几里得距离的结果等于某个值D。 此外,这不能有重复。即两个元组的对(X,Y)和相同的两个元组的(Y,X)不能在结果中。 在没有给我答案的情况下,有没有人能够指导我用sql查询来回答这个问题?我已经绞尽脑汁几个小时了,我不知道该从哪里开始。

  • 问题内容: 我有两个 x - y 坐标数组,我想找到一个数组中 每个 点与另一个数组中 所有 点之间的最小欧几里得距离。数组的大小不一定相同。例如: 我当前的方法遍历每个坐标,并计算该坐标与其他坐标之间的距离。 有没有一种方法可以消除for循环,并以某种方式在两个数组之间进行逐元素计算?我设想生成一个距离矩阵,为此我可以找到每一行或每一列中的最小元素。 看问题的另一种方法。假设我将(length