2013-05-10 25 views
2

说我有一个(3,3,3)这样的数组。如何获得numpy的3x3x3阵列上的欧几里得距离

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]]]) 

我如何获得对应欧氏距离9个值3个值的每个向量与零值之间?

如做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]]]) 
+0

是的,不幸的是,'norm'不允许'axis' arg。我不知道为什么。你可能会在这个[类似的问题]中找到你正在寻找的答案(http://stackoverflow.com/questions/7741878/how-to-apply-numpy-linalg-norm-to-each-row-of-a -matrix) – shx2 2013-05-10 04:17:11

回答

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]]]) 
+0

感谢您的帮助。你可能离答案不远了;我编辑的问题,以显示我是多么需要零值作为编曲[0],而不仅仅是常用3 [0] [0]。 – chimpsarehungry 2013-05-10 13:33:53

+0

@chimpsarehungry,我编辑的答案,只需更换'[1,1,1]''到X [0]',你会得到的结果。 – HYRY 2013-05-10 22:00:38

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认为:

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

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

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

这种方法的最大需要注意的是,我们正在计算n*m*o距离,当我们只需要n*m(和它涉及的疯狂量重塑)。

+0

fgb,我编辑了这个例子来帮助澄清。 – chimpsarehungry 2013-05-10 14:04:47

+0

@chimpsarehungry:我修改后的答案应该解决您的问题。 – fgb 2013-05-10 17:54:38

0

我正在做类似的工作,即计算视频卷中每对帧的平方距离总和(SSD)。我认为这可能对你有帮助。

video_volume是一个单一的4D numpy阵列。此数组的维数应为 (时间,行,列,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() 
+0

谢谢,我的视频也是。如果可以的话,我想避免这样的循环。 – chimpsarehungry 2013-05-10 13:44:28

相关问题