Pandas中稀疏矩阵(行,列,值)高效存储及相似性矩阵优化
高效构建相似性得分矩阵(避免循环中使用pd.concat)
问题背景
需要计算对象列表的相似性指数,生成以对象名为行/列名的矩阵。原代码通过循环中反复调用pd.concat()拼接DataFrame,在对象规模较大时速度极慢,需要更高效的存储和转换方式。
原实现代码:
obj = [o1, o2, o3] names = ["o1","o2","o3"] results = pd.DataFrame(columns= names) for i,o in enumerate(obj): simdict = {} for k in range(i+1, len(obj)): simdict[names[k]] = similarity(o, obj[k]) row = pd.DataFrame([simdict], columns=simdict.keys()) results = pd.concat([results, row], ignore_index=True) results.index = names
原输出结果:
o1 o2 o3 o1 NaN 0.5 1.0 o2 NaN NaN 0.3 o3 NaN NaN NaN
方法1:用三元组列表存储,再转换为DataFrame
这种方式内存占用低,循环中仅记录必要的相似性数据,最后一次性生成矩阵。
import pandas as pd obj = [o1, o2, o3] names = ["o1","o2","o3"] # 存储三元组:(行名称, 列名称, 相似性得分) sim_triples = [] for i, o in enumerate(obj): row_name = names[i] for k in range(i+1, len(obj)): col_name = names[k] score = similarity(o, obj[k]) sim_triples.append( (row_name, col_name, score) ) # 转换为DataFrame并透视成矩阵 df = pd.DataFrame(sim_triples, columns=["row", "col", "score"]) sim_matrix = df.pivot(index="row", columns="col", values="score") # 补充行/列索引,确保所有对象都在矩阵中 sim_matrix = sim_matrix.reindex(index=names, columns=names)
方法2:初始化空矩阵,直接填充上三角值
提前创建指定大小的空DataFrame,循环中直接赋值,避免反复拼接。
import pandas as pd obj = [o1, o2, o3] names = ["o1","o2","o3"] # 初始化空矩阵,行/列都用names,默认值NaN sim_matrix = pd.DataFrame(index=names, columns=names) for i, o in enumerate(obj): row_name = names[i] for k in range(i+1, len(obj)): col_name = names[k] sim_matrix.loc[row_name, col_name] = similarity(o, obj[k])
如果需要对称矩阵(填充下三角),可以在最后添加sim_matrix = sim_matrix.combine_first(sim_matrix.T)完成对称填充。两种方法都避免了循环内的pd.concat()操作,大幅提升大列表场景下的处理性能。
内容的提问来源于stack exchange,提问作者Forinstance
相关产品推荐
相关产品推荐

