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'})]