Node and edge attributes, weights

NetworkX · Essentials · 10 min

Real networks carry information on nodes and edges, and weighted algorithms read it from attributes.

Every node and edge has an attribute dictionary. Set attributes when adding, G.add_edge("a", "b", weight=4.2, kind="road") or G.add_node("a", city="Oslo"), or later through the views:

  • G.nodes["a"]["city"] = "Bergen"
  • G.edges["a", "b"]["weight"] = 3.0, or equivalently G["a"]["b"]["weight"]
  • G.graph["name"] = "roads" for graph-level data

Reading in bulk: G.nodes(data=True) yields (node, attrs), G.edges(data=True) yields (u, v, attrs), and G.edges(data="weight", default=1) yields just one attribute with a fallback. nx.get_node_attributes(G, "city") returns a dict, and nx.set_node_attributes(G, values, "score") sets many at once (edge versions exist too).

Weights are just an attribute, conventionally named weight. Weighted algorithms take a weight= argument naming which attribute to use, for example nx.shortest_path(G, s, t, weight="minutes"). Without it, many algorithms treat every edge as length 1. You can also pass a function weight=lambda u, v, d: ... for computed costs.

G.degree(weight="weight") gives weighted degree, the sum of incident edge weights. Keep attribute names consistent across a graph; missing attributes are a common source of KeyErrors.

Example

import networkx as nx

G = nx.Graph(name="trains")
G.add_edge("Oslo", "Bergen", minutes=420, operator="Vy")
G.add_edge("Oslo", "Gol", minutes=180)
G.add_edge("Gol", "Bergen", minutes=200)
G.nodes["Oslo"]["capital"] = True

print(G.edges["Oslo", "Bergen"]["minutes"])        # 420
print(sorted(G.edges(data="operator", default="?")))
# [('Bergen', 'Gol', '?'), ('Oslo', 'Bergen', 'Vy'), ('Oslo', 'Gol', '?')]
print(nx.get_node_attributes(G, "capital"))        # {'Oslo': True}

print(nx.shortest_path(G, "Oslo", "Bergen"))                    # ['Oslo', 'Bergen']
print(nx.shortest_path(G, "Oslo", "Bergen", weight="minutes"))  # ['Oslo', 'Gol', 'Bergen']
print(G.degree("Oslo", weight="minutes"))          # 600

Remember

  • Nodes, edges and the graph each carry an attribute dict
  • data=True or data="attr" iterates attributes efficiently
  • Weighted algorithms need weight="name"; otherwise edges count as 1

Watch out for

  • Forgetting weight= and getting the path with the fewest hops instead of the lowest cost.

Check yourself

  1. Edges have a 'km' attribute. What does nx.shortest_path(G, a, b) minimise?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: networkx.org/documentation/stable/tutorial.html#adding-attributes-to-graphs-nodes-and-edges