2014-12-04 64 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