在python中获取大特征向量最接近的10个欧几里德邻域的最快方法

在python中获取大特征向量最接近的10个欧几里德邻域的最快方法,python,numpy,distance,euclidean-distance,Python,Numpy,Distance,Euclidean Distance,我有一个numpy数组,它有10000个向量,每个向量中有3000个元素。我想返回最近几对的前10个索引以及它们之间的距离。因此,如果第5行和第7行的最近欧氏距离为0.005,第8行和第10行的第二最近欧氏距离为0.0052,那么我想返回[(8,10,0052),(5,7,005)]。传统的for-loop方法非常缓慢。有没有另一种更快的方法来获取大特征向量的欧几里德邻域(存储为np数组) 我正在做以下工作: l = [] for i in range(0,M.shape[0]): f

我有一个numpy数组,它有10000个向量,每个向量中有3000个元素。我想返回最近几对的前10个索引以及它们之间的距离。因此,如果第5行和第7行的最近欧氏距离为0.005,第8行和第10行的第二最近欧氏距离为0.0052,那么我想返回[(8,10,0052),(5,7,005)]。传统的for-loop方法非常缓慢。有没有另一种更快的方法来获取大特征向量的欧几里德邻域(存储为np数组)

我正在做以下工作:

l = []
for i in range(0,M.shape[0]): 
    for j in range(0,M.shape[0]): 
        if i != j and i > j: 
            l.append( (i,j,euc(M[i],M[j])) 
return l 
这里euc是一个函数,用于使用scipy计算矩阵的两个向量之间的欧氏距离。
然后我对l进行排序,找出前10个最接近的距离,我会将此作为答案发布,但我承认这不是问题的真正解决方案,因为它只适用于较小的阵列。问题是,如果你想变得非常快并避免循环,你需要一次计算所有的成对距离,这意味着内存复杂度是按输入的平方的顺序排列的。。。假设10000行*10000行*3000个元素/行*4个字节/行(假设我们使用float32)≈ 需要1TB(!)的内存(实际上可能需要两倍,因为您可能需要两个这样大小的阵列)。因此,虽然这是可能的,但这种尺寸并不实用。下面的代码显示了如何实现(大小除以100)


这应该很快,因为它只进行排序和前10位的平方根,这是很长的步骤(在循环之外)。

你看到了吗?可能重复我知道如何计算欧几里德距离,并且已经这样做了,但是我正在寻找一种最快的方法,在np数组中的每一对行之间进行竞争,然后对其进行排序并返回前10名。这与其说是如何计算欧几里德距离,不如说是一个速度问题。我知道我可以使用循环或scipyShow你的传统循环方法-也许它可以改进。我不太了解这个方法的输出,但它是fastSay,m=np.array([1,2,3],[2,3,4],[1,6,8],[1,6,9],[2,3,5])。我如何解释这些结果,比如我想将其更改为前8名或前3名之类的?OP想要最接近的前十名或十个最小的距离。@MikeElJackson,-
argpartition
调用中的
-10
值确定返回的数量。对,但矩阵结果让我困惑,其中是什么?
import numpy as np

# Row length
n = 30
# Number of rows
m = 100
# Number of top elements
k = 10

# Input data
data = np.random.random((m, n))
# Tile the data in two different dimensions
data1 = np.tile(data[:, :, np.newaxis], (1, 1, m))
data2 = np.tile(data.T[np.newaxis, :, :], (m, 1, 1))
# Compute pairwise squared distances
dist = np.sum(np.square(data1 - data2), axis=1)
# Fill lower half with inf to avoid repeat and self-matching
dist[np.tril_indices(m)] = np.inf
# Find smallest distance for each row
i = np.arange(m)
j = np.argmin(dist, axis=1)
dmin = dist[i, j]
# Pick the top K smallest distances
idx = np.stack((i, j), axis=1)
isort = dmin.argsort()

# Top K indices pairs (K x 2 matrix)
top_idx = idx[isort[:k], :]
# Top K smallest distances
top_dist = np.sqrt(dmin[isort[:k]])
def topTen(M):
    i,j = np.triu_indices(M.shape[0], 1)
    dist_sq = np.einsum('ij,ij->i', M[i]-M[j], M[i]-M[j])
    max_i=np.argpartition(dist_sq, 10)[:10]
    max_o=np.argsort(dist_sq[max_i])
    return np.vstack((i[max_i][max_o], j[max_i][max_o], dist_sq[max_i][max_o]**.5)).T