NetworkX - 创建反向图的深拷贝
我在使用NetworkX创建一个反向有向图的深拷贝时遇到了问题,想要查看这个拷贝的PageRank(网页排名)。看起来问题不在于PageRank本身,而是在计算这个损坏的反向有向图的PageRank时抛出了异常。
首先,我用这段代码生成一个有向图,基本上就是创建一堆节点,随机选几个,然后从这些节点向另外50个左右随机选的节点画出有向边。最后,去掉所有连接数为0的节点。
def global_classroom(nodes):
network = nx.DiGraph()
network.add_nodes_from([User(i, "0.0.1") for i in range(nodes)])
network_nodes = network.nodes()
teachers = random.sample(network_nodes, nodes / 100)
for teacher in teachers:
for i in range(nodes / 20):
student = network_nodes[random.randrange(nodes)]
if teacher != student:
network.add_edge(teacher, student)
for node in network_nodes:
if network.degree(node) == 0:
network.remove_node(node)
return network
现在,如果我调用这个:
G = global_classroom(1000)
G.reverse(False)
print nx.pagerank(G)
一切都运行得很好。NetworkX可以毫无问题地计算PageRank。
但是如果我调用这个:
G = global_classroom(1000)
G_page_rank = G.reverse()
nx.pagerank(G_page_rank)
就会抛出一个异常。
Traceback (most recent call last):
File "a.py", line 62, in <module>
rank = nx.pagerank(L_page_rank)
File "<string>", line 2, in pagerank
File "/Users/PSnyder/Documents/Git/infection/networkx/utils/decorators.py", line 68, in _not_implemented_for
return f(*args,**kwargs)
File "/Users/PSnyder/Documents/Git/infection/networkx/algorithms/link_analysis/pagerank_alg.py", line 140, in pagerank
dangling_nodes = [n for n in W if W.out_degree(n, weight=weight) == 0.0]
File "/Users/PSnyder/Documents/Git/infection/networkx/classes/digraph.py", line 1023, in out_degree
return next(self.out_degree_iter(nbunch,weight))[1]
File "/Users/PSnyder/Documents/Git/infection/networkx/classes/digraph.py", line 941, in out_degree_iter
for n,nbrs in nodes_nbrs:
File "/Users/PSnyder/Documents/Git/infection/networkx/classes/digraph.py", line 934, in <genexpr>
nodes_nbrs=((n,self.succ[n]) for n in self.nbunch_iter(nbunch))
KeyError: <__main__.User object at 0x104618050>
其中<__main__.User object at 0x104618050>
是我有向图中许多节点之一。
我希望能够简单地进行深拷贝,而不是需要再次反转我的图来恢复到原来的样子。
这里是构成我节点的User类的全部内容:
class User(object):
def __init__(self, name, version, teachers = [], students = []):
self.name = name
self.version = version
G.add_node(self)
self.add_teachers(teachers)
self.add_students(students)
def add_students(self, students):
for student in students:
G.add_edge(self, student)
def add_teachers(self, teachers):
for teacher in teachers:
G.add_edge(teacher, self)
1 个回答
1
也许你的用户对象出了问题?你没有提供这个信息,所以我无法判断这是不是networkx的bug。
这个是可以正常工作的(用整数代替User())
import networkx as nx
import random
def global_classroom(nodes):
network = nx.DiGraph()
network.add_nodes_from([i for i in range(nodes)])
network_nodes = network.nodes()
teachers = random.sample(network_nodes, nodes / 100)
for teacher in teachers:
for i in range(nodes / 20):
student = network_nodes[random.randrange(nodes)]
if teacher != student:
network.add_edge(teacher, student)
for node in network_nodes:
if network.degree(node) == 0:
network.remove_node(node)
return network
if __name__=='__main__':
G = global_classroom(1000)
G.reverse(False)
print nx.pagerank(G).items()[0:5] # first 5