如何高效去除sklearn.euclidean_distances结果中的重复距离值
提取欧氏距离矩阵中的唯一点对距离(保留真实重复)
我使用sklearn.metrics.pairwise.euclidean_distances计算多点间的欧氏距离时,返回的是对称矩阵——每个点对的距离会在矩阵中出现两次(比如点A到B和B到A的距离完全相同)。现在需要高效提取每对点仅出现一次的距离,同时保留不同点对之间真实存在的重复距离(因此不能用np.unique()去重)。
原代码与问题示例
from sklearn.metrics.pairwise import euclidean_distances import numpy as np points = [[1,2], [1,3], [4,5], [2,6]] distances = euclidean_distances(points)
返回的对称距离矩阵:
array([[0. , 1. , 4.24264069, 4.12310563], [1. , 0. , 3.60555128, 3.16227766], [4.24264069, 3.60555128, 0. , 2.23606798], [4.12310563, 3.16227766, 2.23606798, 0. ]])
期望得到的结果(仅保留每对点一次的距离,真实重复距离会保留):
[1.0, 4.242640687119285, 4.123105625617661, 3.605551275463989, 3.1622776601683795, 2.23606797749979]
原循环实现
最初的实现是通过循环提取矩阵的上三角部分(不含对角线):
dist_list = [] for i in range(len(distances)): unique_dist = distances[i][i+1:] dist_list.extend(unique_dist)
更高效的向量化实现
利用numpy的布尔掩码直接提取上三角元素,完全避免Python循环,性能远优于循环实现:
# 生成上三角掩码(k=1表示跳过对角线) upper_tri_mask = np.triu(np.ones(distances.shape, dtype=bool), k=1) # 提取掩码对应的元素并转为列表 dist_list = distances[upper_tri_mask].tolist()
原理说明
np.triu(..., k=1)生成一个与距离矩阵同形状的布尔矩阵,仅上三角区域(对角线以上,不含对角线)的位置为True- 用该掩码索引距离矩阵,直接筛选出所有
i < j的点对距离,正好对应每对点仅计算一次的结果 - 若不同点对存在真实的重复距离,这些值会被完整保留,不会被误去重
内容的提问来源于stack exchange,提问作者MaaikevR
相关产品推荐
相关产品推荐

