如何计算数据集内所有数据点的非零两两互距离?
计算数据集两两数据点距离(排除自身零值)
你的尝试代码(X - X) ** 2会生成全零矩阵,因为这是让每个元素和自身相减,完全没实现不同数据点间距离的计算需求。下面是两种可行的实现方式:
方法一:用Numpy手动实现欧氏距离
欧氏距离是最常用的距离度量,公式为$\sqrt{\sum_{i=1}^{n}(a_i - b_i)^2}$。利用Numpy的广播机制可以高效计算所有两两样本的距离:
import numpy as np # 生成20个10维的随机样本 X = np.random.rand(20, 10) # 扩展维度实现广播,计算所有两两样本的特征差 diff = X[:, np.newaxis, :] - X[np.newaxis, :, :] # 计算差的平方和,得到平方距离 dist_sq = np.sum(diff ** 2, axis=2) # 开根号得到欧氏距离矩阵 dist = np.sqrt(dist_sq) # 将对角线的自身距离(零值)替换为NaN,排除无效值 dist[np.diag_indices_from(dist)] = np.nan print(dist)
关键说明:
- 维度扩展后,
X[:, np.newaxis, :]是(20,1,10),X[np.newaxis, :, :]是(1,20,10),广播相减后得到(20,20,10)的差矩阵,对应每一对样本的特征差异 np.diag_indices_from(dist)获取矩阵对角线的索引,这些位置就是样本自身到自身的距离,设为NaN后可以避免后续分析时的干扰
方法二:用Scipy的现成工具(更简洁)
Scipy提供了专门计算样本间距离的函数,无需手动实现公式:
import numpy as np from scipy.spatial.distance import pdist, squareform X = np.random.rand(20, 10) # 计算所有两两样本的欧氏距离,返回压缩的一维数组(不含自身距离) dist_compressed = pdist(X, metric='euclidean') # 将压缩数组转换为对称距离矩阵 dist_matrix = squareform(dist_compressed) # 屏蔽对角线的自身零值距离 dist_matrix[np.diag_indices_from(dist_matrix)] = np.nan print(dist_matrix)
额外选项:
pdist支持多种距离度量,比如曼哈顿距离可以指定metric='cityblock',余弦相似度用metric='cosine'- 如果不需要完整矩阵,直接使用
dist_compressed即可,它本身就只包含不同样本间的两两距离,没有自身零值
分析样本间远近关系的小技巧
得到距离矩阵后,可以通过以下方式快速分析:
- 用
np.nanmin(dist_matrix, axis=1)获取每个样本的最近邻距离 - 用
np.nanmax(dist_matrix, axis=1)获取每个样本的最远邻距离 - 用Matplotlib绘制热力图:
plt.imshow(dist_matrix, cmap='viridis'),颜色越深代表样本间距离越近
内容的提问来源于stack exchange,提问作者Ana_1960
相关产品推荐
相关产品推荐

