使用Igraph库计算介中心性

3 投票
2 回答
9472 浏览
提问于 2025-04-17 06:40

我是一名水平一般的程序员,但我还是想用igraph这个Python库来研究一个用户在某个论坛中的中心性,看看这对他未来在论坛的贡献有什么影响。

我联系了一个使用NetworkX库做类似事情的人,但由于论坛的规模太大,计算准确的中心性指标几乎是不可能的——这实在是太耗时间了。

这是他写的代码:

import networkx as netx
import sys, csv

if len(sys.argv) is not 2:
   print 'Please specify an input graph.'
   sys.exit(1)

ingraph = sys.argv[1]
graph = netx.readwrite.gpickle.read_gpickle(ingraph)

num_nodes = len(graph.nodes())
print '%s nodes found in input graph.' % num_nodes
print 'Recording data in centrality.csv'

# Calculate all of the betweenness measures
betweenness = netx.algorithms.centrality.betweenness_centrality(graph)
print 'Betweenness computations complete.'
closeness = netx.algorithms.centrality.closeness_centrality(graph)
print 'Closeness computations complete.'

outcsv = csv.writer(open('centrality.csv', 'wb'))

for node in graph.nodes():
   outcsv.writerow([node, betweenness[node], closeness[node]])

print 'Complete!'

我尝试用igraph库写类似的代码(这个库可以快速估算,而不是做精确计算),但我似乎无法把数据写入CSV文件。

我的代码:

import igraph
import sys, csv

from igraph import *

graph = Graph.Read_Pajek("C:\karate.net")

print igraph.summary(graph)

estimate = graph.betweenness(vertices=None, directed=True, cutoff=2)
print 'Betweenness computation complete.'

outcsv = csv.writer(open('estimate.csv', 'wb'))

for v in graph.vs():
   outcsv.writerow([v, estimate[vs]])

print 'Complete!'

我在igraph的文档中找不到如何调用单个顶点(在NetworkX里叫节点),所以我在这方面遇到了错误信息。也许我还忘记了其他的东西;我可能是个太差的程序员,没注意到这些 :P

我哪里做错了呢?

2 个回答

2

为了让大家更明白,下面的代码最终解决了这个问题:

import igraph
import sys, csv

from igraph import *
from itertools import izip

graph = Graph.Read_GML("C:\stack.gml")

print igraph.summary(graph)

my_id_to_igraph_id = dict((v, k) for k, v in enumerate(graph.vs["id"]))

estimate = graph.betweenness(directed=True, cutoff=16)
print 'Betweenness computation complete.'

print graph.vertex_attributes()

outcsv = csv.writer(open('estimate17.csv', 'wb'))

outcsv.writerows(izip(graph.vs["id"], estimate))

print 'Complete!'
1

正如你已经注意到的,igraph中的每个顶点可以通过图对象的vs属性来访问。vs就像一个列表,所以你可以遍历它来获取图中的顶点。每个顶点都是Vertex类的一个实例,而顶点的索引是通过它的index属性来表示的。(需要注意的是,igraph对顶点和边都使用连续的数字索引,所以你需要用index属性,而不能直接使用原来的顶点名称。)

我猜你需要的是原始输入文件中存储的顶点名称。名称存储在nameid顶点属性中(这取决于你的输入格式),所以你可能需要这样做:

for v in graph.vs:
    outcsv.writerow([v["name"], estimate[v.index]])

请注意,顶点属性可以通过将顶点对象当作字典来索引来访问。另一种方法是直接将vs对象当作字典使用;这样你会得到一个包含所有顶点的指定属性值的列表。例如:

from itertools import izip

for name, est in izip(graph.vs["name"], estimate):
    outcsv.writerow([name, est])

还有一种更快的方式,使用生成器表达式:

outcsv.writerows(izip(graph.vs["name"], estimate))

撰写回答