如何高效筛选Pandas DataFrame中行列索引对唯一的单元格?
高效提取对称距离矩阵的唯一非重复对
针对你遇到的对称距离矩阵提取唯一非重复对的需求,完全没必要用效率低下的循环,Pandas和numpy提供了内置的向量化操作,速度能提升几个数量级,下面是两种实用方案:
方案一:利用numpy三角矩阵过滤
通过生成上三角(或下三角)布尔矩阵,直接过滤掉重复和对角线上的元素,再转换为长格式:
import numpy as np import pandas as pd # 假设你的距离矩阵是min_dists # 生成上三角布尔矩阵(k=1表示排除对角线,只保留对角线以上的元素) upper_mask = np.triu(np.ones(min_dists.shape, dtype=bool), k=1) # 过滤出上三角区域的元素,其余设为NaN upper_tri_df = min_dists.where(upper_mask) # 转换为长格式,自动忽略NaN值 unique_pairs = upper_tri_df.stack().reset_index() # 重命名列名 unique_pairs.columns = ['对象ID1', '对象ID2', '距离']
方案二:利用索引比较筛选
先将矩阵转为长格式,再通过行索引和列索引的大小关系筛选唯一对:
import pandas as pd # 把矩阵转为长格式,保留所有索引对和距离 long_format = min_dists.stack().reset_index(name='距离') # 筛选出"对象ID1 < 对象ID2"的行,确保每对只出现一次,同时排除对角元素 unique_pairs = long_format[long_format['level_0'] < long_format['level_1']] # 可选:重命名列名 unique_pairs.columns = ['对象ID1', '对象ID2', '距离']
为什么你的循环方法慢?
你之前的循环里,每次检查str(rowname) + '_' + str(col)是否在measured_pairs列表中是线性查找,时间复杂度为O(N²),当矩阵规模N较大时,会导致性能急剧下降。而上面的两种方案都是基于向量化操作,底层由numpy优化的C代码执行,效率远高于Python循环。
内容的提问来源于stack exchange,提问作者mb475
相关产品推荐
相关产品推荐

