95万行DataFrame计算跨分类共同发布用户共现矩阵方案求助
解决方案
直接用交叉表+矩阵乘法的向量化方案实现,效率最高,完全可以处理95万行规模的数据,核心逻辑如下:
实现代码
import pandas as pd # 第一步:先去重,避免同一用户同一分类多条记录干扰统计 df = df.drop_duplicates(subset=['User', 'Category']) # 第二步:生成用户-分类的0/1交叉表,值为1表示该用户在对应分类下发过内容 user_cate_cross = pd.crosstab(df['User'], df['Category']) # 第三步:交叉表转置乘原表,直接得到共现矩阵 co_occur_matrix = user_cate_cross.T.dot(user_cate_cross)
原理说明
交叉表的行是用户、列是分类,每个单元格是0或1。转置后矩阵的每行代表一个分类的用户分布向量,两个向量做点积的结果就是同时在两个分类下发布内容的用户总数,刚好符合你的需求:
- 矩阵对角线是单个分类的独立发布用户总数
- 非对角线是两个分类的共同发布用户数
- 矩阵天然对称,和你给出的预期输出完全一致
性能优势
- 全程是pandas内置的向量化运算,没有Python层的循环,执行速度极快
- 内存占用远低于遍历方案,如果你的分类数量较多(>1000),还可以把交叉表转成稀疏矩阵进一步降低内存占用:
# 稀疏矩阵优化版本,适合分类数量极多的场景 from scipy.sparse import csr_matrix user_cate_sparse = csr_matrix(user_cate_cross.values) co_occur_sparse = user_cate_sparse.T.dot(user_cate_sparse) co_occur_matrix = pd.DataFrame(co_occur_sparse.todense(), index=user_cate_cross.columns, columns=user_cate_cross.columns)
原有方案的问题说明
- pivot_table写法逻辑错误:你把index和columns都设为category,没有按用户维度做聚合,当然得不到正确结果
- numpy遍历方案逻辑完全错误,且组合遍历的时间/空间复杂度随数据量增长指数上升,数据量大必然内存溢出
内容的提问来源于stack exchange,提问作者idelph
相关产品推荐
相关产品推荐

