求1000组数据基于键值的相似度得分矩阵Python实现方案
问题
现有1000组数据,需计算每组与其余999组的相似度,最终生成1000×1000的相似度得分矩阵。相似度计算规则如下:
- 当两组中相同key1-key6组合对应的value完全匹配时,该组合在两组中各计1次匹配
- 组间相似度得分 = 匹配总次数 / 两组的总价值数量(示例中g1与g2的得分为6/9≈66.67%)
数据样本示例
group, key1, key2, key3, key4, key5, key6, value g1, kg11, kg12, kg13, kg14, kg15, kg16, [0.1] g1, kg111, kg112, kg113, kg114, kg115, kg116, [xyz] g1, kg1111, kg1112, kg1113, kg1114, kg1115, kg1116, None g1, kg11111, kg11112, kg11113, kg11114, kg11115, kg11116, [false] g1, kg111111, kg111112, kg111113, kg111114, kg111115, kg111116, [1123, 2314,5678] g1, kg1111111, kg1111112, kg1111113, kg1111114, kg1111115, kg1111116, [1, 5] g2, kg11, kg12, kg13, kg14, kg15, kg16, [0.2] g2, kg111, kg112, kg113, kg114, kg115, kg116, [xyz] g2, kg1111, kg1112, kg11113, kg11114, kg11115, kg11116, None g2, kg11111, kg11112, kg11113, kg11114, kg11115, kg11116, [true] g2, kg111111, kg111112, kg111113, kg111114, kg111115, kg111116, [1123, 2314,5678] g2, kg1111111, kg1111112, kg1111113, kg1111114, kg1111115, kg1111116, [1, 7]
匹配规则与得分示例
- Value匹配:当两组的key1-key6完全一致,且对应的value内容完全相同时,视为匹配。例如:
g1, kg111, kg112, kg113, kg114, kg115, kg116, [xyz]与g2, kg111, kg112, kg113, kg114, kg115, kg116, [xyz]属于匹配项。 - 得分计算示例:g1有6个条目,g2有6个条目,两者有3个共同key组合且全部匹配,匹配总次数为3×2=6;总价值数量为6+6-3=9,因此得分为6/9≈66.67%。
解决方案
思路概述
- 预处理原始数据,将每组的key1-key6组合转为唯一标识,解析value为可哈希的类型以便比较。
- 构建分组字典,存储每个组的key-value映射,提升匹配查找效率。
- 遍历所有组对,按规则计算相似度得分并填充矩阵。
- 将结果转为DataFrame格式,方便查看和保存。
Python代码实现
import pandas as pd import numpy as np # 1. 读取并预处理数据 # 替换为你的数据文件路径,或直接传入已有的DataFrame df = pd.read_csv('your_data.csv') # 将key1-key6合并为元组作为唯一键,解析value为可哈希类型(处理字符串格式的列表/None) def parse_value(v): if pd.isna(v): return None try: # 将字符串格式的列表转为元组,确保可哈希 return tuple(eval(v)) if isinstance(v, str) and (v.startswith('[') or v.startswith('(')) else v except: # 解析失败时返回原始值 return v df['key_tuple'] = df.apply(lambda row: (row['key1'], row['key2'], row['key3'], row['key4'], row['key5'], row['key6']), axis=1) df['parsed_value'] = df['value'].apply(parse_value) # 2. 构建分组字典:{组名: {key元组: 解析后的value}} group_dict = {} for group_name, group_data in df.groupby('group'): group_dict[group_name] = group_data.set_index('key_tuple')['parsed_value'].to_dict() # 3. 获取所有组名列表 groups = list(group_dict.keys()) n_groups = len(groups) # 4. 初始化相似度矩阵 similarity_matrix = np.zeros((n_groups, n_groups)) # 5. 计算每对组的相似度 for i in range(n_groups): group_i = groups[i] dict_i = group_dict[group_i] len_i = len(dict_i) for j in range(n_groups): group_j = groups[j] dict_j = group_dict[group_j] len_j = len(dict_j) # 找出两组的共同key组合 common_keys = set(dict_i.keys()) & set(dict_j.keys()) # 统计匹配的共同key数量,每个匹配项在两组各计1次 matched_common = sum(1 for key in common_keys if dict_i[key] == dict_j[key]) match_count = matched_common * 2 # 总价值数量:两组条目数之和减去共同key数量(避免重复统计) total_count = len_i + len_j - len(common_keys) # 计算得分,避免除以0 score = match_count / total_count if total_count != 0 else 0.0 # 转为百分比并保留两位小数 similarity_matrix[i][j] = round(score * 100, 2) # 6. 转为DataFrame方便查看和保存 similarity_df = pd.DataFrame(similarity_matrix, index=groups, columns=groups) # 保存结果到CSV文件 similarity_df.to_csv('similarity_matrix.csv') # 打印示例结果(以g1和g2为例) print("相似度矩阵示例:") print(similarity_df.loc[['g1', 'g2'], ['g1', 'g2']])
代码说明
- 数据预处理:将key1-key6合并为元组作为唯一标识,把字符串格式的value(如列表)转为可哈希的元组,确保能作为字典键和进行相等比较。
- 分组字典:每个组的key-value映射存储为字典,后续查找匹配项的时间复杂度为O(1),大幅提升计算效率。
- 相似度计算:严格遵循示例逻辑,匹配次数按“每个共同匹配key计2次”计算,总价值数量按“两组条目数之和减共同key数”计算,保证结果与示例一致。
- 效率适配:针对1000组数据,总计算量为1e6次,基于集合和字典的操作能保证运行效率;若数据量更大,可进一步引入并行计算优化。
内容的提问来源于stack exchange,提问作者Pratibha UR
相关产品推荐
相关产品推荐

