如何从pandas dataframe生成带共现权重的无向边列表
实现两人共现月份无向边权重统计的Pandas方案
方案一:直接生成有效边列表(推荐,效率更高)
不需要先生成全量人员两两组合,直接按月分组生成当月内的人员无向组合,再统计频次即可得到共现权重:
import pandas as pd from itertools import combinations # 按月份遍历生成所有共现人员对 edge_pairs = [] for month, group_df in df.groupby("monthyear"): # 生成当月内的无向两两组合,sorted保证a-b和b-a视为同一对 month_pairs = combinations(sorted(group_df["name"].tolist()), 2) edge_pairs.extend(month_pairs) # 统计每对人员的共现次数 res_df = ( pd.Series(edge_pairs) .value_counts() .reset_index() .rename(columns={"index": "node_pair", 0: "weight"}) ) # 拆分节点对为node1、node2两列 res_df[["node1", "node2"]] = pd.DataFrame(res_df["node_pair"].tolist(), index=res_df.index) # 调整列顺序得到最终结果 res_df = res_df[["node1", "node2", "weight"]].reset_index(drop=True)
该方案仅生成有共现记录的边,不会产生权重为0的无效数据,适合人员基数大、共现关系稀疏的场景,你的示例数据运行后可直接得到预期输出。
方案二:基于已有的全量组合df1填充权重
如果需要保留所有人员两两组合(包括权重为0的对),可以基于你已生成的df1批量计算权重:
# 提前预存每个名字对应的所有月份集合,避免重复计算提升效率 name_to_months = df.groupby("name")["monthyear"].apply(set).to_dict() # 按行计算每对人员的共现月份交集长度,作为权重 df1["weight"] = df1.apply( lambda row: len(name_to_months[row["node1"]] & name_to_months[row["node2"]]), axis=1 ) # 若只需保留权重>0的边,补充执行下行过滤即可 # df1 = df1[df1["weight"] > 0].reset_index(drop=True)
内容的提问来源于stack exchange,提问作者h3rmit
相关产品推荐
相关产品推荐

