Search code examples
pythonnetworkxdirected-graphpytorch-geometricdgl

How to set the DGL node features from networkx graph


I'd like to convert the networkx graph to dgl data.
But when I tried using dgl.from_networkx like tutorial, there was unexpected result.

import dgl
import networkx as nx
import numpy as np
import torch

#Construct the networkx graph G containing three nodes, 2 undirected edges, 
#and three node attributes (i.e., 3-dimension of node features)
G = nx.Graph()

G.add_nodes_from([
    (1, {"x_0": 0.1, "x_1": 0.3, "x_2": 0.7}),
    (2, {"x_0": 0.1, "x_1": 0.3, "x_2": 0.7}),
    (3, {"x_0": 0.1, "x_1": 0.3, "x_2": 0.7}),
])

G.add_edges_from([(1, 2), (2, 1), (1, 3), (3,1)])

#Additionally, I add this code because the original dataset is called from .csv file.
#So, the below code means the list of features
#.csv file: node(row) x features(colum)
cols = list(["x_0", "x_1", "x_2"])

#Convert networkx from dgl
dgl_graph = dgl.from_networkx(G, node_attrs=cols)

#DGL Result
#Graph(num_nodes=3, num_edges=4,
#      ndata_schemes={'x_0': Scheme(shape=(), dtype=torch.float32), 'x_1': Scheme(shape=(), dtype=torch.float32), 'x_2': Scheme(shape=(), dtype=torch.float32)}
#      edata_schemes={})

When I run this in pytorch geometric, it returns what I think.

from torch_geometric.utils.convert import from_networkx

pyg_graph = from_networkx(G, group_node_attrs=all)
pyg_graph

#PyG Result
#Data(edge_index=[2, 4], x=[3, 3])

Does DGL result has the same meaning with PyG result? If not, how can I move the node attributes to DGL node feature?


Solution

  • Does DGL result has the same meaning with PyG result? If not, how can I move the node attributes to DGL node feature?

    DGL graphs are always directional, while pyg_graph will inherit properties from G (which is undirected). This can be verified via pyg_graph.is_directed(). This is why the number of edges in dgl_graph is 4, while the number of edges in the pyg_graph is 2 (the same as in G, can be seen via len(G.edges())). So, while both dgl_graph and pyg_graph have the same underlying network structure, if property of directed-ness matters in your workflow, then these graphs are not the same.

    As regards the node attributes, they are already in the dgl_graph, you can view them using dgl_graph.ndata.