如何在Python中将squareform距离矩阵转换为长格式?
高效转换欧式距离矩阵为长格式(Pandas实现)
这题用Pandas处理简直是小菜一碟,而且完全不需要手动循环,用内置的向量化操作就能搞定,效率拉满!咱们直接上完整流程:
完整代码实现
import numpy as np import pandas as pd from scipy.spatial.distance import pdist, squareform # 原始数据 ids = ['1', '2', '3'] points = [(0,0), (1,1), (3,3)] # 生成距离矩阵 distances = pdist(np.array(points), metric='euclidean') distance_matrix = squareform(distances) # 核心转换步骤 # 1. 把矩阵转成带索引和列名的DataFrame df = pd.DataFrame(distance_matrix, index=ids, columns=ids) # 2. 用stack()把宽表转成长表,自动生成多级索引 long_df = df.stack().reset_index() # 3. 重命名列名到目标格式 long_df.columns = ['id1', 'id2', 'distance'] # 查看结果 print(long_df) # 写入CSV(去掉index=False会保留默认索引列,按需选择) long_df.to_csv('distance_long.csv', index=False)
代码解释
- 第一步:用
pd.DataFrame把距离矩阵包装成DataFrame,同时指定index和columns为ids,让每一行每一列都对应具体的id,为后续转换打好基础。 - 第二步:
stack()是Pandas处理宽表转长表的神器,它会把列名转为二级索引,和原有的行索引组成多级索引,同时把矩阵里的数值作为新的列值。之后用reset_index()把多级索引拆成普通列,这一步是整个转换的核心,完全是向量化操作,效率极高。 - 第三步:给列重命名成你需要的
id1、id2、distance格式即可。
输出结果
运行后得到的长格式DataFrame完全符合你的要求:
id1 id2 distance 0 1 1 0.000000 1 1 2 1.414214 2 1 3 4.242641 3 2 1 1.414214 4 2 2 0.000000 5 2 3 2.828427 6 3 1 4.242641 7 3 2 2.828427 8 3 3 0.000000
如果不需要对角线id1=id2的行,只需要加一行long_df = long_df[long_df['id1'] != long_df['id2']]就能快速过滤。
这种方式的效率最高,因为stack()是Pandas底层优化过的向量化操作,比手动遍历矩阵快得多,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者Mr_and_Mrs_D
相关产品推荐
相关产品推荐

