使用Igraph库计算介中心性
我是一名水平一般的程序员,但我还是想用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
属性,而不能直接使用原来的顶点名称。)
我猜你需要的是原始输入文件中存储的顶点名称。名称存储在name
或id
顶点属性中(这取决于你的输入格式),所以你可能需要这样做:
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))