dgl.to_heterogeneousΒΆ
-
dgl.
to_heterogeneous
(G, ntypes, etypes, ntype_field='_TYPE', etype_field='_TYPE', metagraph=None)[source]ΒΆ Convert a homogeneous graph to a heterogeneous graph and return.
The input graph should have only one type of nodes and edges. Each node and edge stores an integer feature as its type ID (specified by
ntype_field
andetype_field
). DGL uses it to retrieve the type names stored in the givenntypes
andetypes
arguments.The function will automatically distinguish edge types that have the same given type IDs but different src and dst type IDs. For example, it allows both edges A and B to have the same type ID 0, but one has (0, 1) and the other as (2, 3) as the (src, dst) type IDs. In this case, the function will βsplitβ edge type 0 into two types: (0, ty_A, 1) and (2, ty_B, 3). In another word, these two edges share the same edge type name, but can be distinguished by an edge type triplet.
The function stores the node and edge IDs in the input graph using the
dgl.NID
anddgl.EID
names in thendata
andedata
of the resulting graph. It also copies any node/edge features fromG
to the returned heterogeneous graph, except for reserved fields for storing type IDs (dgl.NTYPE
anddgl.ETYPE
) and node/edge IDs (dgl.NID
anddgl.EID
).- Parameters
G (DGLGraph) β The homogeneous graph.
ntype_field (str, optional) β The feature field used to store node type. (Default:
dgl.NTYPE
)etype_field (str, optional) β The feature field used to store edge type. (Default:
dgl.ETYPE
)metagraph (networkx MultiDiGraph, optional) β Metagraph of the returned heterograph. If provided, DGL assumes that G can indeed be described with the given metagraph. If None, DGL will infer the metagraph from the given inputs, which could be costly for large graphs.
- Returns
A heterogeneous graph.
- Return type
Notes
The returned node and edge types may not necessarily be in the same order as
ntypes
andetypes
.Calling
to_homogeneous()
then callingto_heterogeneous()
again yields the same result.
Examples
The following example uses PyTorch backend.
>>> import dgl >>> import torch
>>> hg = dgl.heterograph({ ... ('user', 'develops', 'activity'): (torch.tensor([0, 1]), torch.tensor([1, 2])), ... ('developer', 'develops', 'game'): (torch.tensor([0, 1]), torch.tensor([0, 1])) ... }) >>> print(hg) Graph(num_nodes={'activity': 3, 'developer': 2, 'game': 2, 'user': 2}, num_edges={('developer', 'develops', 'game'): 2, ('user', 'develops', 'activity'): 2}, metagraph=[('developer', 'game', 'develops'), ('user', 'activity', 'develops')])
We first convert the heterogeneous graph to a homogeneous graph.
>>> g = dgl.to_homogeneous(hg) >>> print(g) Graph(num_nodes=9, num_edges=4, ndata_schemes={'_TYPE': Scheme(shape=(), dtype=torch.int64), '_ID': Scheme(shape=(), dtype=torch.int64)} edata_schemes={'_TYPE': Scheme(shape=(), dtype=torch.int64), '_ID': Scheme(shape=(), dtype=torch.int64)}) >>> g.ndata {'_TYPE': tensor([0, 0, 0, 1, 1, 2, 2, 3, 3]), '_ID': tensor([0, 1, 2, 0, 1, 0, 1, 0, 1])} Nodes 0, 1, 2 for 'activity', 3, 4 for 'developer', 5, 6 for 'game', 7, 8 for 'user' >>> g.edata {'_TYPE': tensor([0, 0, 1, 1]), '_ID': tensor([0, 1, 0, 1])} Edges 0, 1 for ('developer', 'develops', 'game'), 2, 3 for ('user', 'develops', 'activity')
Now convert the homogeneous graph back to a heterogeneous graph.
>>> hg_2 = dgl.to_heterogeneous(g, hg.ntypes, hg.etypes) >>> print(hg_2) Graph(num_nodes={'activity': 3, 'developer': 2, 'game': 2, 'user': 2}, num_edges={('developer', 'develops', 'game'): 2, ('user', 'develops', 'activity'): 2}, metagraph=[('developer', 'game', 'develops'), ('user', 'activity', 'develops')])
Retrieve the original node/edge IDs.
>>> hg_2.ndata[dgl.NID] {'activity': tensor([0, 1, 2]), 'developer': tensor([3, 4]), 'game': tensor([5, 6]), 'user': tensor([7, 8])} >>> hg_2.edata[dgl.EID] {('developer', 'develops', 'game'): tensor([0, 1]), ('user', 'develops', 'activity'): tensor([2, 3])}
See also