2014-12-04 105 views
2

我搜索了一下,發現了可比的問題/答案,但沒有一個爲我返回正確的結果。計算numpy中的值之間的加權歐式距離的平均值

情況: 我有一個數值爲== 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)。我的公式,數學或方法有什麼問題嗎?

回答

3

需要非零標記的實際座標,計算它們之間的距離:

>>> 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]返回coords的行i和行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。最後,第2個座標(第1行:[0,0,0])與第3個(最後一行第2行:[0,0,1])之間的距離也爲1。所以請記住,pdist將其第一個參數解釋爲n維空間中的座標堆棧,n是每個節點的元組中的元素數目。

+0

嘿,謝謝你的建議。到目前爲止,我沒有使用'np.where'和'np.vstack'命令,所以我會嘗試一下。可悲的是,它仍然爲我的示例數據集返回了錯誤的值(這個值更大,* 1 *的塊很多,形狀也很不規則)。我的猜測是公式中的某些內容還不正確,但我會調查 – Curlew 2014-12-05 19:24:48

+0

@Curlew,就你描述問題的方式而言,你看起來好像每個「叢」都是單個標記,單個元素(1)被零包圍。然而,如果你有一個實際的「叢」,例如1的連接區域,例如代表粒子在現實生活中的位置,那麼你應該佔據那個叢的中心。但是這改變了你的問題,所以你可能想要考慮問一個新的問題,然後提供關於實際數據集的更多細節(可能是生物體的二元照片?)。 – 2014-12-06 01:31:56