我是Python新手,所以这个问题看起来很琐碎。但是,我没有找到与我类似的情况。我有一个20个节点的坐标矩阵。我想计算这个集合中所有节点对之间的欧氏距离,并将它们存储在一个成对矩阵中。例如,如果我有20个节点,我希望最终结果是一个矩阵(20,20),每对节点之间的欧氏距离值,我尝试使用for循环遍历坐标集的每个元素,并计算欧氏距离,如下所示:
ncoord=numpy.matrix('3225 318;2387 989;1228 2335;57 1569;2288 8138;3514 2350;7936 314;9888 4683;6901 1834;7515 8231;709 3701;1321 8881;2290 2350;5687 5034;760 9868;2378 7521;9025 5385;4819 5943;2917 9418;3928 9770')
n=20
c=numpy.zeros((n,n))
for i in range(0,n):
for j in range(i+1,n):
c[i][j]=math.sqrt((ncoord[i][0]-ncoord[j][0])**2+(ncoord[i][1]-ncoord[j][1])**2)
然而,我得到了一个错误的“输入必须是一个方阵“。我想知道是否有人知道这里发生了什么。谢谢
4条答案
按热度按时间5jdjgkvh1#
除了嵌套的
for
循环,还有很多更快的替代方法,我将向您展示两种不同的方法--第一种是更通用的方法,它将向您介绍广播和矢量化,第二种使用更方便的scipy库函数。1.一般方法,使用广播和矢量化
我建议做的第一件事是改用
np.array
而不是np.matrix
。数组之所以更受欢迎有很多原因,最重要的是因为它们可以有〉2维,而且它们使元素乘法变得不那么笨拙。对于数组,我们可以通过插入一个新的单元素维度和broadcasting对它进行减法运算来消除嵌套的
for
循环:这相当于使用嵌套的for循环遍历每对行,但是要快得多!
剩下的我们也可以使用矢量化操作来完成:
整件事可以在一行中完成,就像这样:
1.使用
pdist
的惰性方法事实证明,已经有一个快速方便的函数可以用来计算所有两两之间的距离:
scipy.spatial.distance.pdist
.bqjvbblv2#
ncoord[i, j]
与Numpy * 矩阵 * 的ncoord[i][j]
不同。这似乎是混淆的来源。如果ncoord
是Numpy * 数组 *,则它们将给出相同的结果。对于Numpy * matrix *,
ncoord[i]
返回ncoord
的第i行,ncoord
本身是一个形状为1 x 2的Numpy * matrix * 对象。因此,ncoord[i][j]
实际上意味着:取ncoord
* 的第i行,并取1 x 2矩阵的第j行,这就是j
〉0时索引问题出现的地方。关于你对
c[i][j]
赋值的评论,它不应该工作,至少在我构建的Numpy1.9.1中,如果你的索引i
和j
迭代到n
,它不应该工作。顺便说一句,记得把矩阵
c
的转置加到它自己上。建议使用Numpy数组而不是矩阵。请参见this post。
如果您的坐标存储为Numpy数组,则成对距离可以计算为:
或者干脆
因为默认度量是"欧几里德",并且默认"p"是2。
在下面的注解中我错误地提到pdist的结果是一个n x n矩阵。要得到一个n x n矩阵,您需要执行以下操作:
或
2sbarzqh3#
我想你想做的是:你说你想要一个20乘20的矩阵...但是你编码的是三角形的。
因此,我编写了一个完整的20x20矩阵。
SciPy方式:
vcirk6k64#
使用你自己定制的sqrt和sqaures并不总是安全的,它们可能上溢或下溢。速度方面它们是一样的
下溢
溢出
无下溢
无溢出
Refer