2014-09-25 75 views
2

我试图在Scipy/Numpy中创建一个二维数组,其中每个值代表距离中心的欧几里得距离。它应该具有与三维阵列的前两个维度相同的形状(图像,通过scipy.misc.fromimage创建)。创建一个二维Numpy阵列与中心的欧几里得距离

这里有一个办法,工作原理:

def get_distance_1(y, x): 
    mid_x, mid_y = (scipy.array(image_array.shape[:2]) - 1)/float(2) 
    return ((y - mid_y) ** 2 + (x - mid_x) ** 2) ** 0.5 

distances = scipy.fromfunction(get_distance_1, image_array.shape[:2]) 

这种方法是相当快的,但我很新的SciPy的,并想知道是否有做同样的事情更优雅,习惯的方法。我发现这个功能似乎很有前途,但我对如何适应这个问题感到不知所措。

def get_distance_2(y, x): 
    mid = ... # needs to be a array of the shape (rows, cols, 2)? 
    return scipy.spatial.distance.cdist(scipy.dstack((y, x)), mid) 

只是为了澄清,我正在寻找的是这样的(一个6×6阵列)

[[ 3.53553391 2.91547595 2.54950976 2.54950976 2.91547595 3.53553391] 
[ 2.91547595 2.12132034 1.58113883 1.58113883 2.12132034 2.91547595] 
[ 2.54950976 1.58113883 0.70710678 0.70710678 1.58113883 2.54950976] 
[ 2.54950976 1.58113883 0.70710678 0.70710678 1.58113883 2.54950976] 
[ 2.91547595 2.12132034 1.58113883 1.58113883 2.12132034 2.91547595] 
[ 3.53553391 2.91547595 2.54950976 2.54950976 2.91547595 3.53553391]] 
+0

同时检查HTTP:/ /stackoverflow.com/questions/17527340/more-efficient-way-to-calculate-distance-in-numpy(当数组变得非常大时,计算距离的不同方法的效率会变化 - 内存开始变得重要,而且解决方案是f astest不是显而易见的) - 为了更加清晰,阅读所有关于问题和已接受答案的评论 – usethedeathstar 2014-09-25 09:46:47

回答

1

cdist是正确的函数。给定两组点XY,它将返回xy之间的所有x之间的距离,其中Xy之间的距离为Y。在这种情况下,这些集之一是单:

>>> X = np.random.randn(10, 3)        # random 3-d points 
>>> center = np.random.randn(3) 
>>> scipy.spatial.distance.cdist(X, np.atleast_2d(center)) # both must be 2-d 
array([[ 2.72130005], 
     [ 1.62765189], 
     [ 1.14245608], 
     [ 2.55279445], 
     [ 2.43727709], 
     [ 3.20647709], 
     [ 1.65028127], 
     [ 0.79044422], 
     [ 1.8180881 ], 
     [ 2.38094952]]) 

这是一个2-d阵列,所以你可能要ravel它:

>>> scipy.spatial.distance.cdist(X, np.atleast_2d(center)).ravel() 
array([ 2.72130005, 1.62765189, 1.14245608, 2.55279445, 2.43727709, 
     3.20647709, 1.65028127, 0.79044422, 1.8180881 , 2.38094952]) 
2

我想说的惯用方式是对其进行矢量化。

原始函数get_distance_1可能设计有标量参数(单个数字),但实际上也可以对Numpy数组进行操作,而无需进行修改。这意味着你可以用x和y索引来传递数组,并且它会给出所需的结果。

import numpy as np 

m, n = image_array.shape[:2] 
x_inds = np.arange(m) 
y_inds = np.arange(n) 

distances = get_distance_1(x_inds[:,None], y_inds) 

None(相当于索引与np.newaxis)索引增加了一个轴的一维向量和有效地调换它。这是参与broadcasting的必要条件。

短的位将是:

x_inds, y_inds = np.ogrid[:m, :n] 

distances = get_distance_1(x_inds, y_inds) 

注意,你必须扭转xget_distance_1y的定义中,以相对于中心距:

def get_distance_1(x, y): 
    mid_x, mid_y = (scipy.array(image_array.shape[:2]) - 1)/float(2) 
    return ((y - mid_y) ** 2 + (x - mid_x) ** 2) ** 0.5 
相关问题