构建igraph图时保留原始节点ID并关联Infomap聚类结果方法问询
问题描述
我通过带编号的边列表加载得到igraph图g,调用community_infomap()方法获取聚类结果后,希望得到一个以原边列表中节点编号为索引的DataFrame/Series,其中包含Infomap分配的聚类编号(即infmap_object.membership),还可选择性包含节点参与的边数量。另外想知道:有没有相关函数或方法实现这个需求?或者能否在创建图时保留原始节点ID,而非让igraph将其重置为递增编号?
代码示例:
import igraph as ig # edges = [(node1, node2, weight), ...] g = ig.Graph.TupleList(edges, weights=True) infmap = g.community_infomap(edge_weights = g.es["weight"]) df_edges = infmap.get_edges_dataframe() --> # df_edges["key1"] != edges[0]["key1"], iGraph重置了我给定的节点编号
解决方法
1. 创建图时保留原始节点ID
使用igraph.Graph.TupleList创建图时,通过vertex_name_attr参数指定一个属性名,让igraph把原始节点编号存储为节点属性,而非直接替换成内部递增ID。
示例代码:
import igraph as ig import pandas as pd # 示例边列表(原始节点编号非连续) edges = [(100, 200, 0.5), (200, 300, 0.8), (100, 300, 0.3)] # 创建图,将原始节点ID存入"original_id"属性 g = ig.Graph.TupleList(edges, weights=True, vertex_name_attr="original_id")
此时每个节点的original_id属性就是你输入的原始编号,igraph内部的index则是自动生成的递增ID,两者可一一对应。
2. 生成目标DataFrame/Series
遍历图中所有节点,将原始ID、聚类编号、节点度(参与的边数量)映射后,转成DataFrame或Series:
包含聚类编号和边数的DataFrame
# 运行Infomap聚类 infmap = g.community_infomap(edge_weights=g.es["weight"]) # 构建节点数据字典 node_info = {} for node in g.vs: node_info[node["original_id"]] = { "cluster_id": infmap.membership[node.index], "edge_count": node.degree() } # 转成DataFrame,索引为原始节点ID result_df = pd.DataFrame.from_dict(node_info, orient="index")
仅含聚类编号的Series
如果只需要聚类编号,可简化为:
result_series = pd.Series( {node["original_id"]: infmap.membership[node.index] for node in g.vs}, name="cluster_id" )
补充说明
你之前用的infmap.get_edges_dataframe()返回的是边层面的DataFrame,且用的是igraph内部节点ID,所以和原始编号不匹配。上面的方法直接处理节点层面的数据,通过original_id属性映射回原始编号,完全满足需求。
内容的提问来源于stack exchange,提问作者Ranger
相关产品推荐
相关产品推荐

