Skip to content
Advertisement

Networkx: Update single attribute of all nodes within a graph without for loop

I have some code that can update a graph‘s attribute:

import networkx as nx

def update_nodes(graph):
    values = dict.fromkeys(graph.nodes, True)
    nx.set_node_attributes(graph, name='test_attribute', values=values)
    print(f"graph.nodes.data(): {graph.nodes.data()}")
    return graph

def loop(graph):
    graph.graph['test_attribute'] = False
    print(f"graph.nodes.data(): {graph.nodes.data()}")
    print(f"graph.graph['test_attribute']: {graph.graph['test_attribute']}")
    for node in range(0, len(graph.nodes)):
        print(f"graph.nodes[node]['test_attribute']: {graph.nodes[node]['test_attribute']}")
    return graph

graph = nx.erdos_renyi_graph(n = 3, p = 0.1, seed = 5)
for i in range(0, 2):
    graph = update_nodes(graph)
    graph = loop(graph)

This doesn’t update the node attribute, and instead applies the update to the graph as a separate entity. Is there any way to mass-update a single attribute of an entire set of nodes without sticking in for node in (range(0, len(graph.nodes)): graph.nodes[node]['test_attribute'] = <new_value> somewhere?

Edit: I should’ve clarified that the reason I’m unhappy with this iteration over the graph’s contents is that this initial value needs to be reset for all nodes prior to the running of a second loop after this that calls into question the value of the attribute and follows different logical paths based on that. So I’m hoping to avoid iterating over all nodes twice, albeit this first loop is much less computationally intensive and hopefully unnecessary.

Advertisement

Answer

If you want to set the attribute for all nodes to the same value, you can use graph.add_nodes_from(graph.nodes,attribute_name='attribute_value')

This updates the provided attribute (adds the node and attribute if non-existent) but maintains any other node attributes and edges you already have in the graph. See the example below:

import networkx as nx

graph = nx.erdos_renyi_graph(n = 3, p = 0.1, seed = 5)

# setup some initial attributes
graph.nodes[0]['attr1'] = 'foo'
graph.nodes[1]['attr1'] = 'bar'
graph.nodes[2]['attr1'] = 'baz'

# make some attribute we want to change
for node in graph.nodes:
    graph.nodes[node]['attr_to_change'] = 'orig_value'

# View initial attribute values
print(graph.nodes(data=True))
# [(0, {'attr1': 'foo', 'attr_to_change': 'orig_value'}),
#  (1, {'attr1': 'bar', 'attr_to_change': 'orig_value'}),
#  (2, {'attr1': 'baz', 'attr_to_change': 'orig_value'})]

# change the value of the attr_to_change attribute for all
graph.add_nodes_from(graph.nodes,attr_to_change='new_value')

# View updated attribute value
print(graph.nodes(data=True))
# [(0, {'attr1': 'foo', 'attr_to_change': 'new_value'}),
#  (1, {'attr1': 'bar', 'attr_to_change': 'new_value'}),
#  (2, {'attr1': 'baz', 'attr_to_change': 'new_value'})]
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement