You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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)

关键说明

  1. 采用无序配对统计,避免重复计算(A,B)和(B,A),最后对称填充矩阵,保证结果一致性
  2. 大规模数据下用pandarallel并行处理分组,大幅缩短运行时间
  3. 自动过滤空值和重复食物,确保统计准确性

内容的提问来源于stack exchange,提问作者Manfred L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:05:32