Python 手动查找质心和标记数据点之间的距离

Python 手动查找质心和标记数据点之间的距离,python,numpy,cluster-analysis,k-means,Python,Numpy,Cluster Analysis,K Means,我对一些数据X进行了聚类分析,得出了标签y和质心c。现在,我正试图计算X与其指定簇的质心c之间的距离。当我们有少量的点时,这很容易: import numpy as np # 10 random points in 3D space X = np.random.rand(10,3) # define the number of clusters, say 3 clusters = 3 # give each point a random label # (in the real code

我对一些数据
X
进行了聚类分析,得出了标签
y
和质心
c
。现在,我正试图计算
X
与其指定簇的质心
c
之间的距离。当我们有少量的点时,这很容易:

import numpy as np

# 10 random points in 3D space
X = np.random.rand(10,3)

# define the number of clusters, say 3
clusters = 3

# give each point a random label 
# (in the real code this is found using KMeans, for example)
y = np.asarray([np.random.randint(0,clusters) for i in range(10)]).reshape(-1,1)

# randomly assign location of centroids 
# (in the real code this is found using KMeans, for example)
c = np.random.rand(clusters,3)

# calculate distances
distances = []
for i in range(len(X)):
    distances.append(np.linalg.norm(X[i]-c[y[i][0]]))
不幸的是,实际数据有更多的行。有没有办法以某种方式将其矢量化(而不是使用
for循环
)?我似乎无法理解映射。

多亏了numpy,您实际上可以将for循环转换为一行,完全避免显式循环:

distances = np.linalg.norm(X- np.einsum('ijk->ik', c[y]), axis=1)
将执行与原始for循环相同的操作

编辑:谢谢@Kris,我忘记了
关键字,因为我没有指定它,numpy自动计算整个展平矩阵的范数,而不仅仅是沿着行(轴1)。我现在已经更新了它,它应该返回每个点的距离数组。此外,@Kris还建议使用einsum作为其特定应用。

多亏了numpy,您可以将for循环变成一行,完全避免显式循环:

distances = np.linalg.norm(X- np.einsum('ijk->ik', c[y]), axis=1)
将执行与原始for循环相同的操作


编辑:谢谢@Kris,我忘记了
关键字,因为我没有指定它,numpy自动计算整个展平矩阵的范数,而不仅仅是沿着行(轴1)。我现在已经更新了它,它应该返回每个点的距离数组。另外,@Kris建议einsum用于他们的特定应用。

Hmm,这只是给了我一个标量值,而不是每个点的距离数组。是的,忘了指定轴了,哈哈-我在上面添加了它。好的,所以你的编辑给了我一个nx3数组,而不是我希望的nx1数组。为了解决这个问题,我必须稍微改变线性方程的右边
np.einsum('ijk->ik',c[y])
而不是
c[y]
似乎是为了获得正确的尺寸。哦,我没有意识到你想要一个标量距离——我假设“距离”是指从每个点到其质心的3D向量。我将把它添加到我的答案中,嗯,这只是给了我一个标量值,而不是每个点的距离数组。是的,忘记指定轴了哈哈-我在上面添加了它。好的,所以你的编辑给了我一个nx3数组,而不是我希望的nx1数组。为了解决这个问题,我必须稍微改变线性方程的右边
np.einsum('ijk->ik',c[y])
而不是
c[y]
似乎是为了获得正确的尺寸。哦,我没有意识到你想要一个标量距离——我假设“距离”是指从每个点到其质心的3D向量。我会把这句话加到我的回答中。你可以试试
scypi
。你可以试试
scypi