Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a node with the same label exists in networkx in python

I am using the following code to build my graph using networkx as follows.

mylist = [('chocolate_pudding', 6.3), ('tim_tam', 178.5), ('bread', 3.5), 
('chocolate_pudding', 8.5), ('tim_tam', 3.0), ('butter', 204.0)]

G = nx.Graph()

for ele in mylist:
    #if node with ele[0] does not exists, add the new node
         G.add_node(ele[0], weight=ele[1])
    #else, update the weight with the new weight value (weight = existing_weight + ele[1])

I want to check if the node with the same label exists before creating a new node. If the node exists I want to update its weight by adding the new value to the existing value.

For example in the above example, I want only 4 nodes chocolate_pudding, tim_tam, bread, butter and their weight should be 14.8, 181.5, 3.5, 204.0 respectively.

I did not find a proper way of doing this in networkx. hence please let me know if this is possible to do in networkx?

like image 498
J Cena Avatar asked Jan 08 '18 01:01

J Cena


People also ask

How many nodes can NetworkX handle?

For NetworkX, a graph with more than 100K nodes may be too large. I'll demonstrate that it can handle a network with 187K nodes in this post, but the centrality calculations were prolonged. Luckily, there are some other packages available to help us with even larger graphs.

Which data type can be used as the content of a node in NetworkX?

In NetworkX, nodes can be any hashable object e.g., a text string, an image, an XML object, another Graph, a customized node object, etc. Python's None object is not allowed to be used as a node.

How do you get all nodes on a graph in NetworkX?

We can use shortest_path() to find all of the nodes reachable from a given node. Alternatively, there is also descendants() that returns all nodes reachable from a given node (though the document specified input G as directed acyclic graph.


2 Answers

You can use ele[0] in G to check whether a label ele[0] is already in there. Updating values are rather straightforward.

import networkx as nx
mylist = [('chocolate_pudding', 6.3), ('tim_tam', 178.5), ('bread', 3.5), ('chocolate_pudding', 8.5), ('tim_tam', 3.0), ('butter', 204.0)]

G = nx.Graph()

for ele in mylist: 
     if ele[0] not in G:
         G.add_node(ele[0], weight=ele[1])
     else:
         new_weight = G.nodes[ele[0]]["weight"] + ele[1]
         # set values
         G.node[ele[0]]["weight"] = new_weight

G.nodes(data=True)        
# NodeDataView({'chocolate_pudding': {'weight': 14.8}, 
#               'tim_tam': {'weight': 181.5}, 
#               'bread': {'weight': 3.5}, 
#               'butter': {'weight': 204.0}})

Edit: This answer is based on networkx 2.0. It seems that before networkx 2.0, nodes is only a function rather than an attribute. Thus, you may need to refer to the documentation for how to update nodes. My guess is G.nodes(data=True)[ele[0]]["weight] = new_weight would work. Or checkout set_node_attributes function.

like image 143
Tai Avatar answered Oct 02 '22 14:10

Tai


I think the easiest way is to calculate these values before building the graph

from collections import defaultdict
import networkx as nx

mylist = [('chocolate_pudding', 6.3), ('tim_tam', 178.5), ('bread', 3.5), 
('chocolate_pudding', 8.5), ('tim_tam', 3.0), ('butter', 204.0)]

d = defaultdict(int)

for n, w in mylist:
    d[n] += w

G = nx.Graph()

for n, w in d.items():
    G.add_node(n, weight=w)

print(nx.get_node_attributes(G, 'weight'))
# {'chocolate_pudding': 14.8, 'tim_tam': 181.5, 'bread': 3.5, 'butter': 204.0}
like image 44
Patrick Haugh Avatar answered Oct 02 '22 15:10

Patrick Haugh