dereferencing attributes from nodes in networkx

Viewed 23

I am writing a program that will represent the spread of potential infections using graphs. In order to do this I am assigning generational attributes to my nodes, however I am having trouble dereferencing my "gen" attribute. The print statement I set up to compare level and gen (which should be equal to trigger the next step in the program) returns this: check 1, level is: {1: 0} g is: 0. How would I go about dereferencing attributes so that they return only the generation and I can compare this to the generation I am currently working on modeling?

for node in G.nodes(): #check through nodes and find the ones in the current gen
    level = nx.get_node_attributes(G, "gen") #get the gen
    print("check 1, level is:", level, "g is:", g)
    if level == g: 
      print("check 2")
      y = scipy.stats.poisson.rvs(mu=r, size=1) #see how many are infected
      N[count] = N[count] + y #how many infected

This is how I assign attributes currently, labeling the number node it is and then assigning it a generation based on a counter

G.add_node(1, gen = count)
1 Answers

nx.get_node_attributes(G, "gen") gives dictionary {node:gen, ...} with all nodes which have gen (and skip nodes which don't have gen) - and you could use it directly with for-loop:

for node in nx.get_node_attributes(G, "gen"):
    gen = G.nodes[node]['gen']

    print('node:', node, 'gen:', gen)

    if gen == g: 
        print("check 2")

or shorter using .items() (because it is dictionary)

for node, gen in nx.get_node_attributes(G, "gen").items():

    print('node:', node, 'gen:', gen)

    if gen == g: 
        print("check 2")

You can also use G.nodes.data() to get dictionary {node:attributes, ...} with all nodes:

for node, attribs in G.nodes.data():
    #gen = attribs['gen']    # it raises error when node doesn't have `gen`
    gen = attribs.get('gen')  # it gives `None` when node doesn't have `gen` 

Minimal working code (one node doesn't have gen)

import networkx as nx

G = nx.Graph()

g = 0

G.add_node(1, gen=g)
G.add_node(2, gen=1)
G.add_node(3)             # without gen
G.add_node(4, gen=g)

for node, gen in nx.get_node_attributes(G, "gen").items():
    #gen = G.nodes[node]['gen']
    print('node:', node, 'gen:', gen)
    if gen == g:
        print("> check 2")

print('---')

for node, attribs in G.nodes.data():
    #gen = attribs['gen']    # it raises error when node doesn't have `gen`
    gen = attribs.get('gen')  # it gives `None` when node doesn't have `gen` 
    print('node:', node, 'attribs:', attribs, 'gen:', gen)
    if gen == g: 
        print("> check 2")

Result:

node: 1 gen: 0
> check 2
node: 2 gen: 1
node: 4 gen: 0
> check 2
---
node: 1 attribs: {'gen': 0} gen: 0
> check 2
node: 2 attribs: {'gen': 1} gen: 1
node: 3 attribs: {} gen: None
node: 4 attribs: {'gen': 0} gen: 0
> check 2

EDIT:

In source code I found examples

https://github.com/networkx/networkx/blob/main/networkx/classes/graph.py#L752

for node, attribs in G.nodes(data=True):
    print('node:', node, 'attribs:', attribs, 'gen:', attribs.get('gen'))
for node, gen in G.nodes(data="gen"):
    print('node:', node, 'gen:', gen)
for node, gen in G.nodes("gen"):
    print('node:', node, 'gen:', gen)
Related