我刚开始使用 scipy/numpy。我有一个 100000*3 的数组,每一行是一个坐标,一个 1*3 的中心点。我想计算数组中每一行到中心的距离并将它们存储在另一个数组中。最有效的方法是什么?
6 回答
我会看看scipy.spatial.distance.cdist
:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html
import numpy as np
import scipy
a = np.random.normal(size=(10,3))
b = np.random.normal(size=(1,3))
dist = scipy.spatial.distance.cdist(a,b) # pick the appropriate distance metric
dist
默认的距离度量相当于:
np.sqrt(np.sum((a-b)**2,axis=1))
虽然cdist
对于大型阵列来说效率更高(在我的机器上,对于您的尺寸问题,cdist
速度快了约 35 倍)。
我会使用欧几里德距离的 sklearn 实现。优点是通过使用矩阵乘法来使用更有效的表达式:
dist(x, y) = sqrt(dot(x, x) - 2 * dot(x, y) + dot(y, y)
一个简单的脚本如下所示:
import numpy as np
x = np.random.rand(1000, 3)
y = np.random.rand(1000, 3)
dist = np.sqrt(np.dot(x, x)) - (dot(x, y) + dot(x, y)) + dot(y, y)
sklearn 文档中很好地描述了这种方法的优点:http: //scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.euclidean_distances.html#sklearn.metrics.pairwise.euclidean_distances
我正在使用这种方法来处理大型数据矩阵(10000、10000),并进行一些小的修改,例如使用 np.einsum 函数。
您还可以使用发展规范(类似于显着身份)。这可能是计算点矩阵距离的最有效方法。
这是我最初在 Octave 中用于 k-Nearest-Neighbors 实现的代码片段,但您可以轻松地将其调整为 numpy,因为它仅使用矩阵乘法(等效为 numpy.dot()):
% Computing the euclidian distance between each known point (Xapp) and unknown points (Xtest)
% Note: we use the development of the norm just like a remarkable identity:
% ||x1 - x2||^2 = ||x1||^2 + ||x2||^2 - 2*<x1,x2>
[napp, d] = size(Xapp);
[ntest, d] = size(Xtest);
A = sum(Xapp.^2, 2);
A = repmat(A, 1, ntest);
B = sum(Xtest.^2, 2);
B = repmat(B', napp, 1);
C = Xapp*Xtest';
dist = A+B-2.*C;
这可能不会直接回答您的问题,但如果您毕竟是粒子对的排列,我发现以下解决方案在某些情况下比 pdist 函数更快。
import numpy as np
L = 100 # simulation box dimension
N = 100 # Number of particles
dim = 2 # Dimensions
# Generate random positions of particles
r = (np.random.random(size=(N,dim))-0.5)*L
# uti is a list of two (1-D) numpy arrays
# containing the indices of the upper triangular matrix
uti = np.triu_indices(100,k=1) # k=1 eliminates diagonal indices
# uti[0] is i, and uti[1] is j from the previous example
dr = r[uti[0]] - r[uti[1]] # computes differences between particle positions
D = np.sqrt(np.sum(dr*dr, axis=1)) # computes distances; D is a 4950 x 1 np array
请参阅我的博客文章,以更深入地了解此问题。
您可能需要以更详细的方式指定您感兴趣的距离函数,但这里是基于平方欧几里得距离inner product
的一个非常简单(且有效)的实现(显然可以推广,直接的方式,到其他类型的距离测量):
In []: P, c= randn(5, 3), randn(1, 3)
In []: dot(((P- c)** 2), ones(3))
Out[]: array([ 8.80512, 4.61693, 2.6002, 3.3293, 12.41800])
P
你的点在哪里,c
是中心。
#is it true, to find the biggest distance between the points in surface?
from math import sqrt
n = int(input( "enter the range : "))
x = list(map(float,input("type x coordinates: ").split()))
y = list(map(float,input("type y coordinates: ").split()))
maxdis = 0
for i in range(n):
for j in range(n):
print(i, j, x[i], x[j], y[i], y[j])
dist = sqrt((x[j]-x[i])**2+(y[j]-y[i])**2)
if maxdis < dist:
maxdis = dist
print(" maximum distance is : {:5g}".format(maxdis))