如何计算DataFrame各列Jaccard相似度并绘制对应热力图
问题原因
你写的代码默认计算的是行与行之间的Jaccard距离,和你需要的「列与列之间」计算目标不符,scipy.spatial.distance.pdist默认将输入矩阵的每行识别为一个样本、每列为特征,所以要计算列之间的相似度需要先对输入矩阵转置。
正确实现方案
步骤1:导入依赖库
import pandas as pd from scipy.spatial.distance import pdist, squareform import seaborn as sns import matplotlib.pyplot as plt
步骤2:构造示例DataFrame
data= [ {'col1':'101', 'col2': '101', 'col3':'1321'}, {'col1':'99', 'col2': '99', 'col3':'101'}, {'col1':'21', 'col2': '23', 'col3':'99'}, {'col1':'47', 'col2': '67', 'col3':'47'}, {'col1':'1321', 'col2': '47', 'col3':'23'} ] df = pd.DataFrame(data)
步骤3:计算列间Jaccard相似度
根据你的业务需求,可以二选一以下两种常用计算逻辑:
方案A:基于集合的Jaccard相似度
计算逻辑为:两列元素去重后组成的两个集合,交集大小除以并集大小。
# 提取每列的元素集合 col_sets = {col: set(df[col]) for col in df.columns} cols = df.columns.tolist() col_num = len(cols) jaccard_sim = pd.DataFrame(index=cols, columns=cols, dtype=float) for i in range(col_num): for j in range(col_num): set_i = col_sets[cols[i]] set_j = col_sets[cols[j]] jaccard_sim.loc[cols[i], cols[j]] = len(set_i & set_j) / len(set_i | set_j)
方案B:基于逐元素匹配的Jaccard相似度
计算逻辑为:逐位置对比两列的元素,相同元素占所有位置的比例,和你最初用pdist的实现思路一致。
# 转置矩阵,把每列转为pdist识别的样本 transposed_arr = df.values.T # 计算距离后转为相似度,再转成方阵格式 jaccard_dist = pdist(transposed_arr, metric='jaccard') jaccard_sim = 1 - squareform(jaccard_dist) # 给结果加上列名和行名 jaccard_sim = pd.DataFrame(jaccard_sim, index=df.columns, columns=df.columns)
步骤4:绘制热力图
plt.figure(figsize=(6, 5)) # annot参数控制显示每个格子的数值,vmin和vmax固定相似度取值范围为0~1 sns.heatmap(jaccard_sim, annot=True, cmap='Blues', vmin=0, vmax=1) plt.title('列间Jaccard相似度热力图') plt.show()
内容的提问来源于stack exchange,提问作者user6402446
相关产品推荐
相关产品推荐

