使用Python计算列的Jaccard相似度并筛选相似度≥80%的行
用Python筛选Excel中Jaccard相似度≥80%的行组
问题说明
现有一个包含数千行数据的Excel文件,结构如下:
| id | letters |
|---|---|
| 1 | A,B,G |
| 2 | B,G |
| 21 | C,D |
| 14 | A,B,C,D |
| 46 | F,E,G,J |
| 35 | X,D,F,A,K |
| 3 | X,D,F,K,A |
| 5 | G,E,F,K,J |
| 56 | G,F,E,J,K |
需要筛选出**Jaccard相似度≥80%**的行组,例如:
- id35和id3的相似度为100%(元素完全一致,仅顺序不同)
- id5、id56相似度100%,id5和id46的相似度为4/5=80%
期望输出格式:
| id | letters | sub-id |
|---|---|---|
| 35 | X,D,F,A,K | 35, 3 |
| 5 | G,E,F,K,J | 5, 56, 46 |
Python实现方案
依赖库安装
先安装所需依赖库:
pip install pandas numpy
完整代码
import pandas as pd from itertools import combinations def jaccard_similarity(set1, set2): """计算两个集合的Jaccard相似度""" intersection = len(set1 & set2) union = len(set1 | set2) return intersection / union if union != 0 else 0.0 def find_similar_groups(df, threshold=0.8): # 将letters列转成集合,消除顺序影响 df['letter_set'] = df['letters'].apply(lambda x: set(x.split(','))) id_group = {} visited = set() # 遍历所有行的两两组合 for (i, row1), (j, row2) in combinations(df.iterrows(), 2): id1, id2 = row1['id'], row2['id'] if id1 in visited or id2 in visited: continue sim = jaccard_similarity(row1['letter_set'], row2['letter_set']) if sim >= threshold: # 合并两个id到同一组 group = {id1, id2} # 处理链式相似(比如A和B相似,B和C相似,则三者归为一组) for existing_id in list(id_group.keys()): if existing_id in group: group.update(id_group[existing_id]) del id_group[existing_id] # 标记组内所有id为已处理 visited.update(group) # 选组内首个出现的id作为主id main_id = next(iter(group)) id_group[main_id] = sorted(group) # 构造结果DataFrame result_rows = [] for main_id, sub_ids in id_group.items(): main_row = df[df['id'] == main_id].iloc[0] result_rows.append({ 'id': main_id, 'letters': main_row['letters'], 'sub-id': ', '.join(map(str, sub_ids)) }) return pd.DataFrame(result_rows) # 读取Excel文件,替换为你的文件路径 df = pd.read_excel('your_data.xlsx') # 生成相似组结果 result_df = find_similar_groups(df) # 保存结果到新Excel result_df.to_excel('similar_groups_result.xlsx', index=False) # 打印控制台结果 print(result_df)
代码说明
- Jaccard相似度计算:通过集合的交集、并集占比计算相似度,自动忽略元素顺序差异。
- 组匹配逻辑:
- 遍历所有行的两两组合,跳过已处理的id避免重复计算
- 若相似度达标,将对应id合并为一组,同时处理链式相似的情况
- 结果输出:以组内任意id作为主id,整理成需求的输出格式,同时保存为Excel文件。
优化提示
如果数据量极大(十万级以上),可以先按集合大小分组,只在相同/相近大小的集合间计算相似度,减少不必要的运算量。
内容的提问来源于stack exchange,提问作者abcabc
相关产品推荐
相关产品推荐

