igraph在Ncol()格式导入边列表后如何填充节点属性?

0 投票
1 回答
1671 浏览
提问于 2025-04-17 13:27

我不太确定这是合并操作,还是两个独立的导入,或者我应该完全重新考虑这个问题。我最开始使用igraph是因为在gephi里玩的时候,我总是采用两步导入,先导入边,然后再导入节点数据。这样的方法在igraph里合适吗?

所以,多亏了最近的一些帮助,我刚刚导入了一个边列表,内容大概是这样的:

123123 321321 1
222222 333333 2
123123 333333 3
222222 321321 4

...使用的导入命令是

import igraph
g = igraph.Graph.Read_Ncol('edgelist.txt')

我想给这个边列表生成的节点添加一些属性。这些属性大概是这样的...

123123 "color:red" "community:1"
222222 "color:blue" "community:2"
321321 "color:red" "community:1"
333333 "color:red" "community:2"

我该如何把这些数据添加到我当前的图里呢?我看到有很多复杂的边列表导入格式,但没有节点列表的格式。我是不是漏掉了什么?难道没有自动把节点数据添加到相应节点的功能吗?

如果没有,能不能推荐一种更简单的方法,把节点数据填充到现有的图里?

我本能地想到了类似这样的方式...

[g.vs["color"] = x for x in node_list.color if g.vs["name"] == node_list.name]
[g.vs["community"] = x for x in node_list.community if g.vs["name"] == node_list.name]

但这看起来实在是太麻烦了。

1 个回答

3

你走在正确的道路上,不过这确实会有点麻烦。之所以麻烦,是因为igraph的底层是用C语言写的,而在C语言中,处理数字(比如顶点和边的ID)要比处理名字(比如顶点和边的名称)简单得多。所以,igraph用从零开始的整数来表示顶点和边,而不是用它们的名字。这就是为什么你需要多做一步,才能从名字找到对应的顶点。

我可能会这样做:

  1. 使用 Graph.Read_Ncol 来读取边列表。(你已经做过了)。
  2. 建立一个字典,把顶点名字和它们的ID对应起来:

    >>> id_mapping = dict((v, k) for k, v in g.vs["name"])
    
  3. 把你的属性文件读入 node_list。我假设 node_list.name 会给我一个顶点名字的列表,而 node_list.color 会给我一个对应颜色的列表。然后你可以这样做:

    >>> for name, color in izip(node_list.name, node_list.color):
    ...     g.vs[id_mapping[name]]["color"] = color
    

在第三步中,还有一种替代的方法是使用 g.vs.find(name),这会给你一个 Vertex 对象,指向具有给定名字的顶点。然后你可以把属性分配给这个顶点;例如:

>>> for name, color in izip(node_list.name, node_list.color):
...     g.vs.find(name)["color"] = color

在这种情况下,你就不需要 id_mapping 了。实际上,igraph在后台维护了一个名字到ID的映射,专门用于 name 这个顶点属性,而 g.vs.find 就是利用了这个映射。如果你想用其他顶点属性作为唯一标识,而不是 name,那么基于 id_mapping 的方法会更有用。

撰写回答