2014-09-25 78 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 
相關問題