如何用Pandas高效生成两列DataFrame的全量交集计数矩阵?
高效计算博主粉丝交集计数方阵的Pandas方案
嘿,我来帮你搞定这个问题!你之前用双重循环确实效率太低,尤其是数据量大的时候会特别慢。其实我们可以利用矩阵乘法的向量化操作来高效实现这个需求,步骤很清晰:
步骤1:准备示例数据(你可以替换成自己的DataFrame)
先把你给的示例数据转成Pandas DataFrame:
import pandas as pd data = [ ['A', 'c'], ['A', 'd'], ['A', 'e'], ['A', 'f'], ['A', 'g'], ['A', 'h'], ['A', 'i'], ['A', 'j'], ['A', 'k'], ['B', 'c'], ['B', 'f'], ['B', 'g'], ['B', 'l'], ['B', 'm'], ['B', 'n'], ['B', 'o'], ['B', 'p'], ['B', 'q'], ['B', 'r'], ['B', 's'], ['B', 't'], ['B', 'k'], ['C', 'a'], ['C', 'k'], ['C', 'r'], ['C', 'g'], ['C', 't'], ['C', 'c'], ['C', 'p'], ['C', 'y'], ['C', 'z'], ['C', 'w'] ] df = pd.DataFrame(data, columns=['blogger', 'follower'])
步骤2:构建博主-粉丝的二进制矩阵
我们用crosstab生成一个矩阵,行是博主ID,列是粉丝ID,每个位置的值是1(该博主拥有这个粉丝)或0(没有):
blogger_follower_matrix = pd.crosstab(df['blogger'], df['follower']).astype(int)
步骤3:计算两两博主的粉丝交集数量
这个矩阵和它的转置做矩阵乘法,得到的结果就是两两博主之间的共同粉丝数——因为矩阵乘法中,(i,j)位置的值就是i博主和j博主所有粉丝列的对应值相乘后求和,正好是共同粉丝的数量:
intersection_matrix = blogger_follower_matrix.dot(blogger_follower_matrix.T)
步骤4:替换对角线为'-'
按照你的示例,对角线(博主和自己的交集)显示为'-',我们用Numpy快速替换:
import numpy as np np.fill_diagonal(intersection_matrix.values, '-')
最终结果
运行完上面的代码,intersection_matrix就是你想要的方阵:
A B C blogger A - 4 3 B 4 - 6 C 3 6 -
为什么这个方法高效?
这个方案完全依赖Pandas和Numpy的向量化操作,底层是用C语言实现的,比Python层面的双重循环快几个数量级,数据量越大优势越明显。你之前尝试的pivot_table、crosstab其实是正确的方向,只是没结合矩阵乘法来完成最后一步~
内容的提问来源于stack exchange,提问作者Edgard Gomez Sennovskaya
相关产品推荐
相关产品推荐

