N点与numpy / scipy中的参考之间的有效距离计算

时间:2011-06-21 18:21:03

标签: python arrays numpy scipy

我刚刚开始使用scipy / numpy。我有一个100000 * 3阵列,每行是一个坐标,一个1 * 3中心点。我想计算数组中每行到中心的距离,并将它们存储在另一个数组中。最有效的方法是什么?

6 个答案:

答案 0 :(得分:27)

我会看看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倍)。

答案 1 :(得分:5)

我会使用欧几里德距离的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函数。

答案 2 :(得分:1)

您还可以使用规范的发展(类似于卓越的身份)。这可能是计算点矩阵距离的最有效方法。

这是我最初在Octave中用于k-Nearest-Neighbors实现的代码片段,但您可以很容易地将其调整为numpy,因为它只使用矩阵乘法(相当于numpy.dot()):< / p>

% 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;

答案 3 :(得分:1)

这可能不会直接回答你的问题,但是如果你已经完成了粒子对的排列,我发现以下解决方案在某些情况下比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

在我的博客文章中,请参阅this以更深入地了解此事。

答案 4 :(得分:0)

您可能需要更详细地指定您感兴趣的距离函数,但这是基于inner product的{​​{3}}的非常简单(高效)的实现(显然可以推广) ,直截了当地采取其他类型的距离措施):

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是中心。

答案 5 :(得分:0)

#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))