如何用Python/Pandas按组比较列并识别满足子集关系的相似分组?
Python/Pandas 实现子集相似分组识别
问题背景
现有如下结构的数据集:
type value a 1 a 2 a 3 a 4 b 2 b 3 b 4 b 5 c 1 c 3 c 4 d 2 d 3 d 4
需求:识别满足某一type的所有value完全包含于另一type的value集合的相似分组(例如type d的value集合是type a的子集,故二者属于相似分组),最终输出带相似性标注的结果或生成CSV文件说明相似分组。
实现步骤
1. 数据读取与预处理
先用Pandas读取数据,处理空行后按type分组,生成每个type对应的value集合:
import pandas as pd # 读取数据(替换为你的文件路径,也可直接从字符串读取) df = pd.read_csv('data.txt', sep='\s+', skip_blank_lines=True) # 按type分组,生成每个type的value集合 type_value_sets = df.groupby('type')['value'].apply(set).reset_index(name='value_set')
2. 识别子集关系
遍历所有type组合,判断子集关系(排除自身对比):
similar_pairs = [] # 遍历所有type对 for i, row_i in type_value_sets.iterrows(): type_i, set_i = row_i['type'], row_i['value_set'] for j, row_j in type_value_sets.iterrows(): type_j, set_j = row_j['type'], row_j['value_set'] # 跳过自身,且检查set_i是否是set_j的子集 if i != j and set_i.issubset(set_j): similar_pairs.append({ 'subset_type': type_i, 'superset_type': type_j, 'subset_values': set_i, 'superset_values': set_j }) # 转换为DataFrame方便后续处理 result_df = pd.DataFrame(similar_pairs)
3. 输出结果
打印带标注的文本结果
print("相似分组关系:") for _, row in result_df.iterrows(): print(f"Type {row['subset_type']} 的value集合是 Type {row['superset_type']} 的子集") print(f" {row['subset_type']} 的values: {sorted(row['subset_values'])}") print(f" {row['superset_type']} 的values: {sorted(row['superset_values'])}\n")
输出示例:
相似分组关系: Type d 的value集合是 Type a 的子集 d 的values: [2, 3, 4] a 的values: [1, 2, 3, 4] Type d 的value集合是 Type b 的子集 d 的values: [2, 3, 4] b 的values: [2, 3, 4, 5]
生成CSV文件
将结果保存为CSV,方便后续查看或分析:
# 将集合转换为逗号分隔的字符串,避免CSV存储问题 result_df['subset_values'] = result_df['subset_values'].apply(lambda x: ','.join(map(str, sorted(x)))) result_df['superset_values'] = result_df['superset_values'].apply(lambda x: ','.join(map(str, sorted(x)))) # 保存到CSV文件 result_df.to_csv('similar_groups.csv', index=False)
生成的similar_groups.csv内容示例:
subset_type,superset_type,subset_values,superset_values d,a,2,3,4,1,2,3,4 d,b,2,3,4,2,3,4,5
优化提示
如果数据集较大,可先按集合大小排序,让小集合只和更大的集合对比,减少无意义的遍历,提升效率:
# 按集合大小升序排序 type_value_sets['set_size'] = type_value_sets['value_set'].apply(len) type_value_sets = type_value_sets.sort_values('set_size').reset_index(drop=True) # 仅小集合对比大集合 similar_pairs = [] for i in range(len(type_value_sets)): type_i, set_i = type_value_sets.loc[i, 'type'], type_value_sets.loc[i, 'value_set'] for j in range(i+1, len(type_value_sets)): type_j, set_j = type_value_sets.loc[j, 'type'], type_value_sets.loc[j, 'value_set'] if set_i.issubset(set_j): similar_pairs.append({ 'subset_type': type_i, 'superset_type': type_j, 'subset_values': set_i, 'superset_values': set_j })
内容的提问来源于stack exchange,提问作者user12180847
相关产品推荐
相关产品推荐

