如何基于DataFrame计算两两共现矩阵?
大规模DataFrame食物共现矩阵生成方案
问题描述
现有80万行、16列的DataFrame,每行记录用户的多个食物选择(空值表示未选),需要生成一个对称矩阵,矩阵中[f1][f2]的值表示食物f1和f2出现在同一行的次数,对角线值为0。
示例数据
import pandas as pd dict1 = {'id':['person1','person2','person3','person4','person5'], 'food1':['A','A','A','C','D' ], 'food2':['B','C','B','A','B'], 'food3':['','D','C','',''], 'food4':['','','D','','',] } demo = pd.DataFrame(dict1)
解决方案
基础实现(适合小规模数据验证)
import pandas as pd from itertools import combinations from collections import Counter # 提取每行非空食物 def extract_foods(row): return [val for val in row.filter(like='food') if val.strip()] # 生成所有行的食物列表 food_lists = demo.apply(extract_foods, axis=1).tolist() # 生成所有无序配对(避免重复统计(A,B)和(B,A)) all_pairs = [] for foods in food_lists: if len(foods) >= 2: all_pairs.extend(combinations(sorted(foods), 2)) # 统计配对次数 pair_counts = Counter(all_pairs) # 获取所有唯一食物并排序 unique_foods = sorted({food for sublist in food_lists for food in sublist}) # 构建对称矩阵 result = pd.DataFrame(0, index=unique_foods, columns=unique_foods) for (f1, f2), cnt in pair_counts.items(): result.loc[f1, f2] = cnt result.loc[f2, f1] = cnt print(result)
运行结果:
A B C D A 0 2 3 2 B 2 0 1 2 C 3 1 0 2 D 2 2 2 0
大规模数据优化方案(适配80万行数据)
针对百万级数据,采用长格式转换+分组并行处理,提升效率:
import pandas as pd from itertools import combinations from pandarallel import pandarallel # 初始化并行处理 pandarallel.initialize(nb_workers=4) # 根据CPU核心数调整 # 将宽表转长表,过滤空值 melted = demo.melt(id_vars='id', value_name='food') melted = melted[melted['food'].str.strip() != ''].dropna(subset=['food']) # 按用户分组生成食物配对 def generate_pairs(group): foods = sorted(group['food'].unique()) # 去重避免重复食物的无效配对 if len(foods) >= 2: return list(combinations(foods, 2)) return [] # 并行分组处理,生成所有配对 all_pairs = melted.groupby('id').parallel_apply(generate_pairs).explode().dropna() # 统计配对次数 pair_counts = all_pairs.value_counts() # 构建对称矩阵 unique_foods = sorted(melted['food'].unique()) result = pd.DataFrame(0, index=unique_foods, columns=unique_foods) for (f1, f2), cnt in pair_counts.items(): result.loc[f1, f2] = cnt result.loc[f2, f1] = cnt print(result)
关键说明
- 采用无序配对统计,避免重复计算(A,B)和(B,A),最后对称填充矩阵,保证结果一致性
- 大规模数据下用
pandarallel并行处理分组,大幅缩短运行时间 - 自动过滤空值和重复食物,确保统计准确性
内容的提问来源于stack exchange,提问作者Manfred L
相关产品推荐
相关产品推荐

