使用Python广播的内存高效L2规范

使用Python广播的内存高效L2规范,python,numpy,euclidean-distance,array-broadcasting,Python,Numpy,Euclidean Distance,Array Broadcasting,我试图实现一种方法,使用欧几里德距离,根据测试数据集中的点与样本数据集中的相似性,对点进行聚类。测试数据集有500个点,每个点是一个N维向量(N=1024)。训练数据集大约有10000个点,每个点也是一个1024维的向量。目标是找到每个测试点和所有样本点之间的L2距离,以找到最近的样本(不使用任何python距离函数)。由于测试阵列和训练阵列的大小不同,我尝试使用广播: import numpy as np dist = np.sqrt(np.sum( (test[:,np.ne

我试图实现一种方法,使用欧几里德距离,根据测试数据集中的点与样本数据集中的相似性,对点进行聚类。测试数据集有500个点,每个点是一个N维向量(N=1024)。训练数据集大约有10000个点,每个点也是一个1024维的向量。目标是找到每个测试点和所有样本点之间的L2距离,以找到最近的样本(不使用任何python距离函数)。由于测试阵列和训练阵列的大小不同,我尝试使用广播:

    import numpy as np
    dist = np.sqrt(np.sum( (test[:,np.newaxis] - train)**2, axis=2))
其中,测试是一个形状数组(5001024),列车是一个形状数组(10000124)。我收到了一封回忆录。但是,相同的代码适用于较小的阵列。例如:

     test= np.array([[1,2],[3,4]])
     train=np.array([[1,0],[0,1],[1,1]])
有没有一种更有效的方法可以在没有循环的情况下进行上述计算?基于在线帖子,我们可以使用矩阵乘法sqrt(X*X-2*X*Y+Y*Y)实现L2-范数。因此,我尝试了以下方法:

    x2 = np.dot(test, test.T)
    y2 = np.dot(train,train.T)
    xy = 2* np.dot(test,train.T)

    dist = np.sqrt(x2 - xy + y2)
由于矩阵具有不同的形状,当我尝试广播时,存在维度不匹配,我不确定广播的正确方式(没有太多Python广播经验)。我想知道在Python中将L2距离计算实现为矩阵乘法的正确方法是什么,其中矩阵具有不同的形状。合成距离矩阵的dist[i,j]=测试点i和采样点j之间的欧氏距离


谢谢

简化版和工作版,来自:

因此,你心目中的方法是正确的,但你需要小心如何应用它


<>为了让你的生活更轻松,考虑使用测试或验证的函数,从.O/P> < P>这里有中间形状的广播:

m = x.shape[0] # x has shape (m, d)
n = y.shape[0] # y has shape (n, d)
x2 = np.sum(x**2, axis=1).reshape((m, 1))
y2 = np.sum(y**2, axis=1).reshape((1, n))
xy = x.dot(y.T) # shape is (m, n)
dists = np.sqrt(x2 + y2 - 2*xy) # shape is (m, n)

on broadcasting有一些非常好的例子。

我认为您所要求的已经以函数的形式存在于scipy中

from scipy.spatial.distance import cdist
res = cdist(test, train, metric='euclidean')

那么,对于长度为1024的向量,您要寻找总共5E6个距离?你的最终形状应该是(50010000)或(10000500)?它应该是(50010000)。测试点是行,采样点是距离矩阵的列。最后一行中只需稍加修改
dists=np.sqrt(x2+y2-2*x(y.T))
from scipy.spatial.distance import cdist
res = cdist(test, train, metric='euclidean')