【发布时间】:2020-09-15 17:58:55
【问题描述】:
我有多个节点列表和边列表,它们形成了一个大图,我们称之为maingraph。我目前的策略是首先读取所有节点列表并使用add_vertices 导入它。然后每个节点都会获得一个内部 id,这取决于它们被摄取的顺序,因此不是很可靠(正如我所读到的,如果你删除一个,所有比删除的更改更高的 id)。我为每个节点分配了一个 name 属性,该属性对应于我使用的外部 ID,因此我可以在框架和 type 属性之间跟踪我的节点。
现在,如何添加边缘?当我读取一个边缘列表时,它将开始制作一个新图 (subgraph),因此内部 ID 从 0 开始。因此,将图与maingraph.add_edges(subgraph.get_edgelist)“合并”不可避免地会失败。
可以解决这个问题并使用maingraph 和subgraph 中的name 属性来找出每个边的事件节点在maingraph 中具有哪个内部ID:
def _get_real_source_and_target_id(edge):
''' takes an edge from the to-be-added subgraph and gets the ids of the corresponding nodes in the
maingraph by their name '''
source_id = maingraph.vs.select(name_eq=subgraph.vs[edge[0]]["name"])[0].index
target_id = maingraph.vs.select(name_eq=subgraph.vs[edge[1]]["name"])[0].index
return (source_id,target_id)
然后我尝试了
edgelist = [_get_real_source_and_target_id(x) for x in subgraph.get_edgelist()]
maingraph.add_edges(edgelist)
但这太慢了。该图有数百万个节点和边,使用快速但不正确的maingraph.add_edges(subgraph.get_edgelist) 方法加载需要 10 秒。使用上面解释的正确方法,它需要几分钟(我通常在 5 分钟后停止它)。我将不得不这样做成千上万次。由于加载速度快,我从 NetworkX 切换到了 Igraph,但如果我必须这样做,它并没有真正的帮助。
有没有人有更聪明的方法来做到这一点?非常感谢任何帮助!
谢谢!
【问题讨论】:
-
您可能想查看
igraph支持论坛,我相信您的问题已经是answered。 -
感谢提供链接,我会看看它是否比我的解决方案更快。