Reputation: 65
I'm having an issue when trying to create a deep copy of a reversed digraph in NetworkX and examining the PageRank of that copy. It doesn't appear that the issue is with PageRank, it just throws an exception when trying to calculate the PageRank of the broken reversed digraph.
First, I generate a digraph using this code, which basically just creates a bunch of nodes, randomly picks a few of them, and then draws directed edges from that node to another 50 or so randomly selected nodes. It then trims all nodes with degree 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
Now, if I call this:
G = global_classroom(1000)
G.reverse(False)
print nx.pagerank(G)
Everything works perfectly fine. NetworkX is able to calculate the PageRank no problem.
But if I call this:
G = global_classroom(1000)
G_page_rank = G.reverse()
nx.pagerank(G_page_rank)
There is an exception thrown
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>
Where <__main__.User object at 0x104618050>
is one of the many objects that make up the nodes in my digraph.
I'd like to be able to simply make a deep copy instead of needing to reverse my graph once again to revert it to its original form.
Here is the entirety of the User class which makes up my nodes:
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)
Upvotes: 0
Views: 890
Reputation: 25289
Maybe your User object is causing an issue? You didn't include that so I can't see if this is a networkx bug or not.
This works (using integers instead of 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
Upvotes: 1