Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

removing isolated vertices in networkx

The documentation says that isolated vertices in graph can be obtained using networkx.isolates(G). It adds that the isolated vertices can be removed from a graph G using the code G.remove_nodes_from(nx.isolates(G)).

https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.algorithms.isolate.isolates.html

screenshot of documentation(url above)

But I get the run time error "dictionary changed size during iteration" when I run the code.

Error report:-
>>> G.remove_nodes_from(nx.isolates(G)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/classes/graph.py", line 617, in remove_nodes_from for n in nodes: File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/algorithms/isolate.py", line 94, in <genexpr> return (n for n, d in G.degree() if d == 0) File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/classes/reportviews.py", line 443, in __iter__ for n in self._nodes: RuntimeError: dictionary changed size during iteration

It is understandable and was expected because (I think) the generator object created using the function isolates() changes with G and hence changing graph G while it is being 'iterated' should give a similar error. Then that line in the documentation must be wrong, isn't it? Am I completely off the mark? I am pretty new to python.

By the way, the object returned by networkx.isolates() is a generator object.

Thank you

like image 412
Cyriac Antony Avatar asked Feb 16 '18 05:02

Cyriac Antony


People also ask

How do I delete an isolated node in NetworkX?

The documentation says that isolated vertices in graph can be obtained using networkx. isolates(G). It adds that the isolated vertices can be removed from a graph G using the code G. remove_nodes_from(nx.

How do you remove a node from a graph in Python?

The Graph. remove_nodes_from() method takes a list (container actually) of nodes. So you just need to create a list that satisfies your condition. You can use Python's list comprehension structure to compactly create a list of nodes to delete.

Is NetworkX scalable?

Due to its dependence on a pure-Python "dictionary of dictionary" data structure, NetworkX is a reasonably efficient, very scalable, highly portable framework for network and social network analysis.

What is a DiGraph NetworkX?

A DiGraph stores nodes and edges with optional data, or attributes. DiGraphs hold directed edges. Self loops are allowed but multiple (parallel) edges are not. Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.


2 Answers

I think you are right, submit a documentation patch?

also you can cast the generator to a list to get around this:

G.remove_nodes_from(list(nx.isolates(G)))

But why does your work-around work? I don't understand it; the situation has not changed!

I would have to look at their code, but my hunch is the lazyness of a generator is working against it based on the Exception message.

Casting to list, the collection is created before it is fed as an argument, so there is no side effects on the object as it is iterated.

As noted from @Dyz's answer, the documentation is correct, you are using Nx 2.0.

https://networkx.github.io/documentation/networkx-2.0/reference/algorithms/generated/networkx.algorithms.isolate.isolates.html

Does this collection creation before fed as argument behaviour hold for any kind of cast (say to dict or set) ? –

Well not quite (a set will work) dict won't because it wants a pair of items. list and set when called like a function (and dict but again it needs pairs (a list of tuples will work)) calls __iter__

Generators have __iter__ which makes them iterables (+ a lot of other objects). Generators are really nice to have to address various usecases, for example when you have a large collection of items, and need to loop through them multiple times, it can save you on runtime complexity.

However, there is nuances such as what you ran into, where you have to understand some of the internals for proper use.

like image 130
salparadise Avatar answered Sep 22 '22 08:09

salparadise


You are looking at the docs for 1.X while using 2.X. Unfortunately the search engine ranking is higher for the 1.X documentation.

In networkx 2.X isolates is a generator object.

The current stable docs will add list() to the example code.

https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.isolate.isolates.html

In [107]: nx.isolates(G)
Out[107]: <generator object isolates.<locals>.<genexpr> at 0x7fa499cd8e60>

The migration guide may help out if you are expecting 1.X behavior too.

https://networkx.github.io/documentation/stable/release/migration_guide_from_1.x_to_2.0.html

like image 32
gdahlm Avatar answered Sep 22 '22 08:09

gdahlm