【问题标题】:Calculate average weighted euclidean distance between values in numpy计算numpy中值之间的平均加权欧几里得距离
【发布时间】:2015-02-02 23:46:30
【问题描述】:

我搜索了一下,发现了类似的问题/答案,但没有一个为我返回正确的结果。

情况: 我有一个包含许多值 == 1 的数组,而其余单元格设置为零。每个单元格都是一个正方形(宽度=高度)。 现在我想计算所有 1 值之间的平均距离。 公式应该是这样的:d = sqrt ( (( x2 - x1 )*size)**2 + (( y2 - y1 )*size)**2 )

示例:

import numpy as np
from scipy.spatial.distance import pdist

a = np.array([[1, 0, 1],
              [0, 0, 0],
              [0, 0, 1]])

# Given that each cell is 10m wide/high
val = 10
d = pdist(a, lambda u, v: np.sqrt( ( ((u-v)*val)**2).sum() ) )
d
array([ 14.14213562,  10.        ,  10.        ])

之后我会通过d.mean() 计算平均值。然而,d 中的结果显然是错误的,因为顶行单元格之间的距离应该已经是 20(两个交叉单元格 * 10)。我的公式、数学或方法有问题吗?

【问题讨论】:

    标签: python arrays numpy scipy euclidean-distance


    【解决方案1】:

    您需要非零标记的实际坐标来计算它们之间的距离:

    >>> import numpy as np
    >>> from scipy.spatial.distance import squareform, pdist
    >>> a = np.array([[1, 0, 1],
    ...               [0, 0, 0],
    ...               [0, 0, 1]])
    >>> np.where(a)
    (array([0, 0, 2]), array([0, 2, 2]))
    >>> x,y = np.where(a)
    >>> coords = np.vstack((x,y)).T
    >>> coords
    array([[0, 0],   # That's the coordinate of the "1" in the top left,
           [0, 2],   # top right,
           [2, 2]])  # and bottom right.
    

    接下来您要计算这些点之间的距离。您为此使用pdist,如下所示:

    >>> dists = pdist(coords) * 10  # Uses the Euclidean distance metric by default.
    >>> squareform(dists)
    array([[  0.        ,  20.        ,  28.28427125],
           [ 20.        ,   0.        ,  20.        ],
           [ 28.28427125,  20.        ,   0.        ]])
    

    在最后一个矩阵中,您将找到(在对角线上方)a 中每个标记点与另一个坐标之间的距离。在这种情况下,您有 3 个坐标,因此它给出了节点 0 (a[0,0]) 和节点 1 (a[0,2])、节点 0 和节点 2 (a[2,2]) 之间以及节点 1 和节点 2 之间的距离. 换句话说,如果S = squareform(dists),那么S[i,j]返回coordsi行与j行的坐标之间的距离。

    只有最后一个矩阵的上三角形中的值也出现在变量dist 中,您可以从中轻松得出平均值,而无需执行相对昂贵的squareform 计算(此处仅显示用于演示目的):

    >>> dists
    array([ 20.        ,  28.2842712,  20.        ])
    >>> dists.mean()
    22.761423749153966
    

    请注意,由于您选择的示例,您的计算解决方案“看起来”几乎正确(除了因子 2)。 pdist 的作用是取 n 维空间中的第一个点和第二个点之间的欧几里得距离,然后是第一个和第三个点之间的欧几里得距离,依此类推。在您的示例中,这意味着它计算第 0 行上的点之间的距离:该点在[1,0,1] 给出的 3 维空间中具有坐标。第二点是[0,0,0]。这两个sqrt(2)~1.4 之间的欧几里得距离。那么,第一个坐标和第三个坐标(a 中的最后一行)之间的距离只有1。最后,第二个坐标(第 1 行:[0,0,0])和第 3 个坐标(最后一行,第 2 行:[0,0,1])之间的距离也是1。所以请记住,pdist 将其第一个参数解释为 n 维空间中的坐标堆栈,n 是每个节点的元组中的元素数。

    【讨论】:

    • 嘿,谢谢你的建议。到目前为止,我没有使用 np.wherenp.vstack 命令,所以我会尝试一下。可悲的是,它仍然为我的示例数据集返回错误的值(它要大得多,并且 1 的团块非常糟糕且形状不规则)。我的猜测是公式中的某些东西还不太对,但我会调查
    • @Curlew,按照你描述问题的方式,你让每个“团块”看起来都是一个标记,一个被零包围的单个元素 (1)。但是,如果您有一个实际的“团块”,例如 1 的连接区域,例如代表一个粒子在现实生活中的位置,那么你应该取那个团块的中心。但这会改变您的问题,因此您可能需要考虑提出一个新问题并提供有关实际数据集的更多详细信息(它可能是生物的二进制照片吗?)。
    猜你喜欢
    • 1970-01-01
    • 2015-09-23
    • 2020-02-21
    • 2013-04-07
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多