【问题标题】:How can I calculate the distances of a set of 3d points with each other using python?如何使用 python 计算一组 3d 点之间的距离?
【发布时间】:2015-03-01 03:42:49
【问题描述】:

我有一组 3D 点,我需要在其中找到每个点与所有其他点的距离。到目前为止,我想出了如下代码来计算两个连续(按数组顺序)点之间的距离,但无法弄清楚如何计算每个点与所有其他点的距离。每个点将有 9 个距离(还有 9 个其他点),因此 10 个点总共有 45 个距离(90 的一半)。到目前为止,我只找到了 9 个距离。知道如何使用 python 有效地获得所有距离吗?

import numpy as np
import scipy as sp

rij_mat = np.zeros((9,1),dtype=np.float32) """created a 9x1 matrix for storing 9 distances for 10 points"""

npoints = 10

x = sp.randn(npoints,3)

print "here are the 3-d points..."
print x

for i in xrange(npoints-1):

 rij_mat[i] = np.linalg.norm(x[i+1]-x[i])

print "the distances are..."
print rij_mat

我现在的输出是这样的:

here are the 3-d points...
[[-0.89513316  0.05061497 -1.19045606]
 [ 0.31999847 -0.68013916 -0.14576028]
 [ 0.85442751 -0.64139512  1.70403995]
 [ 0.55855264  0.56652717 -0.17086825]
 [-1.22435021  0.25683649  0.85128921]
 [ 0.80310031  0.82236372 -0.40015387]
 [-1.34356018  1.034942    0.00878305]
 [-0.65347726  1.1697195  -0.45206805]
 [ 0.65714623 -1.07237429 -0.75204526]
 [ 1.17204207  0.89878048 -0.54657068]]
the distances are...
[[ 1.7612313 ]
 [ 1.92584431]
 [ 2.24986649]
 [ 2.07833028]
 [ 2.44877243]
 [ 2.19557977]
 [ 0.84069204]
 [ 2.61432695]
 [ 2.04763007]]

【问题讨论】:

  • 您没有 90 个独特的距离。其中一半是重复计算,所以你只有 45 个。
  • 对不起,你是对的。将有 45 个距离。

标签: python


【解决方案1】:

对于您的每个npoints 点,正好有npoints - 1 其他点可用于比较距离。而且,x[m]x[n] 之间的距离与x[n]x[m] 之间的距离相同,因此将距离总数减半。 itertools 包有一个很好的方法来处理这个问题:

import numpy as np
import scipy as sp
import itertools as its

npoints = 10
nCombos = (npoints * (npoints - 1))/2
x = sp.randn(npoints,3)
rij_mat = np.zeros(nCombos)

ii = 0
for i1, i2 in its.combinations(range(npoints), 2):
    rij_mat[ii] = np.linalg.norm(x[i1]-x[i2])
    ii += 1

print "the distances are..."
print rij_mat

如果你是一个非常细心的人,你可能会检查最后ii == nCombos

既然您将输出矩阵称为rij_mat,也许您打算将其设为二维矩阵?然后你会想要这样的东西:

import numpy as np
import scipy as sp
import itertools as its

npoints = 10

x = sp.randn(npoints,3)
rij_mat = np.zeros((npoints, npoints))

for i1, i2 in its.combinations(range(npoints), 2):
    rij_mat[i2, i1] = rij_mat[i1, i2] = np.linalg.norm(x[i1]-x[i2])

print "the distances are..."
print rij_mat

【讨论】:

  • 谢谢,但我怎样才能确保一个点的距离不从自身算起,这会使它为零。最终,我想为一个点找到最近的邻居,如果我的距离为零,这将是一个问题。
  • its.combinations(range(npoint), 2) 总是从列表中返回 2 个不同的对象。如果您使用 rij_mat[ii] 1D 返回方案,则其中不应包含任何零,除非您在位置中有重复项。
【解决方案2】:

两个循环而不是一个怎么样?

distances = []
for i in xrange(npoints-1):
    for j in range(i+1, npoints):
        distances.append(np.linalg.norm(x[i]-x[j])

【讨论】:

  • 如果你考虑到norm()ij的交换下是对称的,你可以做一半的计算。
  • 在某种意义上,它已经考虑到了这一点。因为 j 总是大于 i。
猜你喜欢
  • 2019-01-10
  • 2022-07-21
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多