dgl.to_simpleο
- dgl.to_simple(g, return_counts='count', writeback_mapping=False, copy_ndata=True, copy_edata=False, aggregator='arbitrary')[source]ο
Convert a graph to a simple graph without parallel edges and return.
For a heterogeneous graph with multiple edge types, DGL treats edges with the same edge type and endpoints as parallel edges and removes them. Optionally, one can get the the number of parallel edges by specifying the
return_counts
argument. To get the a mapping from the edge IDs in the input graph to the edge IDs in the resulting graph, setwriteback_mapping
to true.- Parameters:
g (DGLGraph) β The input graph. Must be on CPU.
return_counts (str, optional) β
If given, the count of each edge in the original graph will be stored as edge features under the name
return_counts
. The old features with the same name will be replaced.(Default: βcountβ)
writeback_mapping (bool, optional) β
If True, return an extra write-back mapping for each edge type. The write-back mapping is a tensor recording the mapping from the edge IDs in the input graph to the edge IDs in the result graph. If the graph is heterogeneous, DGL returns a dictionary of edge types and such tensors.
If False, only the simple graph is returned.
(Default: False)
copy_ndata (bool, optional) β
If True, the node features of the simple graph are copied from the original graph.
If False, the simple graph will not have any node features.
(Default: True)
copy_edata (bool, optional) β
If True, the edge features of the simple graph are copied from the original graph. If there exists duplicate edges between two nodes (u, v), the feature of the edge is the aggregation of edge feature of duplicate edges.
If False, the simple graph will not have any edge features.
(Default: False)
aggregator (str, optional) β
Indicate how to coalesce edge feature of duplicate edges. If
arbitrary
, select one of the duplicate edgesβ feature. Ifsum
, compute the summation of duplicate edgesβ feature. Ifmean
, compute the average of duplicate edgesβ feature.(Default:
arbitrary
)
- Returns:
DGLGraph β The graph.
tensor or dict of tensor β The writeback mapping. Only when
writeback_mapping
is True.
Notes
If
copy_ndata
is True, the resulting graph will share the node feature tensors with the input graph. Hence, users should try to avoid in-place operations which will be visible to both graphs.This function discards the batch information. Please use
dgl.DGLGraph.set_batch_num_nodes()
anddgl.DGLGraph.set_batch_num_edges()
on the transformed graph to maintain the information.Examples
Homogeneous Graphs
Create a graph for demonstrating to_simple API. In the original graph, there are multiple edges between 1 and 2.
>>> import dgl >>> import torch as th >>> g = dgl.graph((th.tensor([0, 1, 2, 1]), th.tensor([1, 2, 0, 2]))) >>> g.ndata['h'] = th.tensor([[0.], [1.], [2.]]) >>> g.edata['h'] = th.tensor([[3.], [4.], [5.], [6.]])
Convert the graph to a simple graph. The return counts is stored in the edge feature βcntβ and the writeback mapping is returned in a tensor.
>>> sg, wm = dgl.to_simple(g, return_counts='cnt', writeback_mapping=True) >>> sg.ndata['h'] tensor([[0.], [1.], [2.]]) >>> u, v, eid = sg.edges(form='all') >>> u tensor([0, 1, 2]) >>> v tensor([1, 2, 0]) >>> eid tensor([0, 1, 2]) >>> sg.edata['cnt'] tensor([1, 2, 1]) >>> wm tensor([0, 1, 2, 1]) >>> 'h' in g.edata False
Heterogeneous Graphs
>>> g = dgl.heterograph({ ... ('user', 'wins', 'user'): (th.tensor([0, 2, 0, 2, 2]), th.tensor([1, 1, 2, 1, 0])), ... ('user', 'plays', 'game'): (th.tensor([1, 2, 1]), th.tensor([2, 1, 1])) ... }) >>> g.nodes['game'].data['hv'] = th.ones(3, 1) >>> g.edges['plays'].data['he'] = th.zeros(3, 1)
The return counts is stored in the default edge feature βcountβ for each edge type.
>>> sg, wm = dgl.to_simple(g, copy_ndata=False, writeback_mapping=True) >>> sg Graph(num_nodes={'game': 3, 'user': 3}, num_edges={('user', 'wins', 'user'): 4, ('game', 'plays', 'user'): 3}, metagraph=[('user', 'user'), ('game', 'user')]) >>> sg.edges(etype='wins') (tensor([0, 2, 0, 2]), tensor([1, 1, 2, 0])) >>> wm[('user', 'wins', 'user')] tensor([0, 1, 2, 1, 3]) >>> sg.edges(etype='plays') (tensor([2, 1, 1]), tensor([1, 2, 1])) >>> wm[('user', 'plays', 'game')] tensor([0, 1, 2]) >>> 'hv' in sg.nodes['game'].data False >>> 'he' in sg.edges['plays'].data False >>> sg.edata['count'] {('user', 'wins', 'user'): tensor([1, 2, 1, 1]) ('user', 'plays', 'game'): tensor([1, 1, 1])}