聚类分析:从原点查找数据框中质心的欧几里得距离的问题

Cluster Analysis: Problem finding Euclidean distances of centroids in a dataframe from origin

df_centroids 中每行的 7 列显示 7 维 space 中的坐标。

import numpy as np 
import pandas as pd 
import scipy
df_centroids

        0           1           2           3           4            5          6
0   2.443664    -0.158806   -0.403137   0.609063    -0.412371   -0.486611   -0.687598
1   -0.389052   1.258986    -0.517471   -0.127748   0.379712    -0.486611   -0.143564
2   -0.215555   0.201088    1.149816    -0.501471   0.275600    -0.088475   1.434132
3   -0.227075   -0.806379   -0.412111   -0.174150   -0.417327   -0.401676   -0.234962
4   -0.130615   0.197548    1.282325    -0.940454   0.161774    2.167632    -0.263252
5   0.015202    -0.125552   -0.665733   1.792274    -0.360096   -0.390093   -0.044649

我正在尝试计算距原点的欧氏距离并将其保存在 'Euclidean Distance' 列下。请看下面的代码:

df_centroids['Euclidean Distance']=''
from scipy.spatial import distance

i=0
while i<len(df_centroids.index):
    centroid=[df_centroids.iloc[i,0], df_centroids.iloc[i,1], df_centroids.iloc[i,2], df_centroids.iloc[i,3], df_centroids.iloc[i,4], df_centroids.iloc[i,5], df_centroids.iloc[i,6]]
    df_centroids[i,7]=distance.euclidean([0, 0, 0, 0, 0, 0, 0], centroid)
    i+=1
df_centroids

       0            1          2          3             4           5           6      'Euclidean Distance'     (0, 7)      (1, 7)       (2, 7)       (3, 7)      (4, 7)     (5, 7)      (6, 7)      (7, 7)
0   2.443664    -0.158806   -0.403137   0.609063    -0.412371   -0.486611   -0.687598                       2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
1   -0.389052   1.258986    -0.517471   -0.127748   0.379712    -0.486611   -0.143564                       2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
2   -0.215555   0.201088    1.149816    -0.501471   0.275600    -0.088475   1.434132                        2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
3   -0.227075   -0.806379   -0.412111   -0.174150   -0.417327   -0.401676   -0.234962                       2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
4   -0.130615   0.197548    1.282325    -0.940454   0.161774    2.167632    -0.263252                       2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
5   0.015202    -0.125552   -0.665733   1.792274    -0.360096   -0.390093   -0.044649                       2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
6   0.256554    1.422368    1.139299    -0.917565   6.804388    -0.486611   0.726889                        2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439
7   6.010360    0.643581    2.401293    -1.193860   0.068166    1.636784    0.726889                        2.722099    1.556305    1.949607    1.136964    2.716432    1.988787    7.161965    6.851439

如您所见,代码不是计算欧几里得 space,而是创建 8 个新列并为所有行复制相同的一组值。我哪里错了?

我已经尝试在网上查找解决方案,但到目前为止还没有成功。非常感谢任何帮助。

在您的代码中您缺少 .iloc,应该是:

df.iloc[i, 7]

而不是:

df[i, 7]

为了避免此类错误,我会使用 apply:

sample = {'a': [2, 2, 3],'b': [3, 5, 2], 'c': [3, 6, 2]}
df = pd.DataFrame(sample)
origin = [0,0,0]
df['distance'] = df.apply(lambda x: distance.euclidean(origin, x), axis=1)
print(df)
>>>     a   b   c   distance
>>> 0   2   3   3   4.690416
>>> 1   2   5   6   8.062258
>>> 2   3   2   2   4.123106

使用 numpy 时,您通常不必使用循环。大多数用例都存在经过高度调整的向量和矩阵运算。

对于您的问题,请注意到原点的欧氏距离与欧氏范数相同。有一个function in numpy.linalg

计算一个向量的欧氏 (l-2) 范数:

import np
np.linalg.norm([1, 2, 3])
# 3.7416573867739413

要为每一行单独计算 行向量 矩阵的范数(如您的问题):

np.linalg.norm([[1,2,3],
                [4,5,6]], axis=1)
# array([3.74165739, 8.77496439])

要为每个列单独计算 列向量 矩阵的范数:

np.linalg.norm([[1, 4],
                [2, 5],
                [3, 6]], axis=0)
# array([3.74165739, 8.77496439])