如何将含商品列表的DataFrame列转换为共现邻接矩阵
实现方案
不需要手动预处理邻接矩阵,以下两种方法都可以基于你现有的DataFrame直接生成带共现权重的商品图,也可以导出你需要的邻接矩阵。
方法1:逐单累加边权重(推荐,内存占用低,适配大数据量)
不用提前生成全量邻接矩阵,遍历每笔订单的商品组合直接给边权重计数,数据量较大时运行效率更高。
import pandas as pd import networkx as nx from itertools import combinations # 测试用示例数据,和你给出的样例一致 df = pd.DataFrame({ 'receipt_no': [0, 1, 2, 3], 'items': [ ['2672', '121431', '121', '49292', '1827'], ['331', '131', '121'], ['121', '49292', '1313'], ['131345', '24', '2314', '194', '91913'] ] }) G = nx.Graph() for items in df['items']: # 单笔订单内商品两两组合,先去重避免同商品对重复计数 for a, b in combinations(set(items), 2): if G.has_edge(a, b): G[a][b]['weight'] += 1 else: G.add_edge(a, b, weight=1)
如果需要导出邻接矩阵,直接调用NetworkX内置方法即可:
# 输出的矩阵行/列均为商品ID,单元格值为两商品共现小票数,对角线为0 adj_matrix = nx.to_pandas_adjacency(G, weight='weight', dtype=int)
用示例数据运行后,adj_matrix中121和49292对应值为2,121和131、331对应值为1,和你给出的邻接矩阵样例完全一致。
方法2:矩阵运算直接生成邻接矩阵(适合小数据集)
如果数据量不大,可以先通过独热编码+矩阵乘法直接算出邻接矩阵,再导入NetworkX,方便后续做矩阵类分析:
# 把商品列表转成订单-商品独热表,每行对应1笔订单,每列对应1个商品 order_item_dummy = df['items'].apply(lambda x: '|'.join(set(x))).str.get_dummies(sep='|') # 矩阵乘法直接得到共现次数 adj_matrix = order_item_dummy.T @ order_item_dummy # 对角线置0,排除商品和自身的共现 for item in adj_matrix.columns: adj_matrix.loc[item, item] = 0 # 从邻接矩阵直接生成带权图 G = nx.from_pandas_adjacency(adj_matrix)
注意事项
- 两种方法生成的图
G中,每条边的weight属性就是两商品共同出现的小票次数,可直接用于关联规则计算、社区划分、可视化等后续操作。 - 如果单张小票存在同一商品多次记录的情况,代码里已经用
set(items)做了去重,不会出现计数虚高的问题。
内容的提问来源于stack exchange,提问作者doit21
相关产品推荐
相关产品推荐

