【问题标题】:How to get euclidean distance on a 3x3x3 array in numpy如何在 numpy 中获取 3x3x3 数组的欧几里得距离
【发布时间】:2013-05-04 16:57:18
【问题描述】:

假设我有一个像这样的 (3,3,3) 数组。

array([[[1, 1, 1],
        [1, 1, 1],
        [0, 0, 0]],

       [[2, 2, 2],
        [2, 2, 2],
        [2, 2, 2]],

       [[3, 3, 3],
        [3, 3, 3],
        [1, 1, 1]]])

如何获得对应于 3 个值的每个向量与第零个值之间的欧几里得距离的 9 个值?

比如做numpy.linalg.norm([1,1,1] - [1,1,1]) 2次,然后norm([0,0,0] - [0,0,0]),然后norm([2,2,2] - [1,1,1]) 2次,norm([2,2,2] - [0,0,0]),然后norm([3,3,3] - [1,1,1]) 2次,最后norm([1,1,1] - [0,0,0])

有什么好的方法来矢量化它吗?我想将距离存储在 (3,3,1) 矩阵中。

结果是:

array([[[0. ],
        [0. ],
        [0. ]],

       [[1.73],
        [1.73],
        [3.46]]

       [[3.46],
        [3.46],
        [1.73]]])

【问题讨论】:

  • 是的,很遗憾,norm 不允许使用 axis 参数。我不知道为什么。您可能会在 similar question 中找到您想要的答案

标签: python matrix numpy scipy linear-algebra


【解决方案1】:

您可能希望考虑scipy.spatial.distance.cdist(),它有效地计算两种输入集合对的点之间的距离(标准欧几里德度量等)。这是示例代码:

import numpy as np
import scipy.spatial.distance as dist

i = np.array([[[1, 1, 1],
               [1, 1, 1],
               [0, 0, 0]],
              [[2, 2, 2],
               [2, 2, 2],
               [2, 2, 2]],
              [[3, 3, 3],
               [3, 3, 3],
               [1, 1, 1]]])
n,m,o = i.shape

# compute euclidean distances of each vector to the origin
# reshape input array to 2-D, as required by cdist
# only keep diagonal, as cdist computes all pairwise distances
# reshape result, adapting it to input array and required output
d = dist.cdist(i.reshape(n*m,o),i[0]).reshape(n,m,o).diagonal(axis1=2).reshape(n,m,1)

d holds:

array([[[ 0.        ],
        [ 0.        ],
        [ 0.        ]],

       [[ 1.73205081],
        [ 1.73205081],
        [ 3.46410162]],

       [[ 3.46410162],
        [ 3.46410162],
        [ 1.73205081]]])

这种方法的最大警告是,当我们只需要 n*m 时,我们正在计算 n*m*o 距离(并且它涉及大量的重塑)。

【讨论】:

  • @ chimpsarehungry:我的修改答案应该解决你的澄清。 span>
【解决方案2】:

keepdims 参数在 numpy 1.7 中添加,您可以使用它来保持和轴:

np.sum((x - [1, 1, 1])**2, axis=-1, keepdims=True)**0.5

结果是:

[[[ 0.        ]
  [ 0.        ]
  [ 0.        ]]

 [[ 1.73205081]
  [ 1.73205081]
  [ 1.73205081]]

 [[ 3.46410162]
  [ 3.46410162]
  [ 0.        ]]]

编辑

np.sum((x - x[0])**2, axis=-1, keepdims=True)**0.5

结果是:

array([[[ 0.        ],
        [ 0.        ],
        [ 0.        ]],

       [[ 1.73205081],
        [ 1.73205081],
        [ 3.46410162]],

       [[ 3.46410162],
        [ 3.46410162],
        [ 1.73205081]]])

【讨论】:

  • 感谢您的帮助。您可能离答案不远了;我编辑了问题以显示我如何需要 arr[0] 中的第零个值,而不仅仅是 arr[0][0]。
  • @chimpsarehungry,我编辑了答案,只需将[1,1,1] 替换为x[0] 即可。
【解决方案3】:

我正在做类似的事情,即计算视频量中每对帧的平方距离之和 (SSD)。我认为它可能对您有所帮助。

video_volume 是一个单一的 4d numpy 数组。这个数组应该有维度 (time, rows, cols, 3) 和 dtype np.uint8.

输出是一个 dtype float 的方形 2d numpy 数组。输出[i,j] 应该包含 帧 i 和 j 之间的 SSD。

video_volume = video_volume.astype(float)
size_t = video_volume.shape[0]
output = np.zeros((size_t, size_t), dtype = np.float)
for i in range(size_t):
    for j in range(size_t):
        output[i, j] = np.square(video_volume[i,:,:,:] - video_volume[j,:,:,:]).sum()

【讨论】:

  • 谢谢,我的也是一个视频。如果可以的话,我想避免这样的循环。
猜你喜欢
  • 2010-11-26
  • 2015-09-23
  • 2014-06-09
  • 1970-01-01
  • 2013-03-02
相关资源
最近更新 更多