dgl.compact_graphs
- dgl.compact_graphs(graphs, always_preserve=None, copy_ndata=True, copy_edata=True)[源代码]
给定一组具有相同节点集合的图,查找并删除所有图中共同的孤立节点。
此函数要求图具有相同的节点集合(即节点类型必须相同,并且每种节点类型的节点数量也必须相同)。元图(metagraph)不必相同。
它查找在所有给定图中具有零入度和零出度的所有节点,并从所有图中删除它们。
这对于图采样非常有用,当您有一个巨大的图,但只想在一个只有一小部分节点的更小图上执行消息传递时。
- 参数:
graphs (DGLGraph 或 list[DGLGraph]) –
图,或图的列表。
所有图必须位于相同的设备上。
所有图必须具有相同的节点集合。
always_preserve (Tensor 或 dict[str, Tensor], 可选) –
如果给定节点类型和节点 ID 张量的字典,则指定节点类型的节点将不会被移除,无论它们是否是孤立的。
如果给定一个 Tensor,DGL 会假定所有图都具有一个(相同的)节点类型。
copy_ndata (bool, 可选) –
如果为 True,返回的图的节点特征将从原始图中复制。
如果为 False,返回的图将不包含任何节点特征。
(默认值:True)
copy_edata (bool, 可选) –
如果为 True,返回的图的边特征将从原始图中复制。
如果为 False,返回的图将不包含任何边特征。
(默认值:True)
- 返回:
压缩后的图,或压缩后的图的列表。
每个返回的图将具有一个特征
dgl.NID
,其中包含从压缩后的图到原始图的每种节点类型的节点 ID 映射。请注意,对于所有压缩后的图,此映射是相同的。所有返回的图都在 CPU 上。
- 返回类型:
注意
此函数目前要求所有图中的相同节点类型应具有相同的节点类型 ID,即节点类型是按相同顺序排列的。
如果
copy_edata
为 True,结果图将与输入图共享边特征张量。因此,用户应尽量避免会被两个图都看到的就地操作。此函数会丢弃批量信息。请在转换后的图上使用
dgl.DGLGraph.set_batch_num_nodes()
和dgl.DGLGraph.set_batch_num_edges()
来保留该信息。示例
以下代码构建了一个包含 20 个用户和 10 个游戏的二分图,但只有用户 #1 和 #3 以及游戏 #3 和 #5 之间存在连接
>>> g = dgl.heterograph({('user', 'plays', 'game'): ([1, 3], [3, 5])}, >>> {'user': 20, 'game': 10})
以下代码会将上面的图压缩成另一个只有两个用户和两个游戏的二分图。
>>> new_g = dgl.compact_graphs(g) >>> new_g.ndata[dgl.NID] {'user': tensor([1, 3]), 'game': tensor([3, 5])}
映射告诉我们,只有用户 #1 和 #3 以及游戏 #3 和 #5 被保留下来。此外,压缩图中的第一个用户和第二个用户分别映射到原始图中的用户 #1 和 #3。游戏的情况类似。
可以验证压缩图中的边连接与原图相同。
>>> new_g.edges(form='all', order='eid', etype='plays') (tensor([0, 1]), tensor([0, 1]), tensor([0, 1]))
当压缩多个图时,在任何给定图中没有任何连接的节点都会被移除。因此,如果您将
g
和以下g2
图一起压缩>>> g2 = dgl.heterograph({('user', 'plays', 'game'): ([1, 6], [6, 8])}, >>> {'user': 20, 'game': 10}) >>> new_g, new_g2 = dgl.compact_graphs([g, g2]) >>> new_g.ndata[dgl.NID] {'user': tensor([1, 3, 6]), 'game': tensor([3, 5, 6, 8])}
然后可以看到,来自两个图的用户 #1,来自第一个图的用户 #3,以及来自第二个图的用户 #6 都被保留下来。游戏的情况类似。
同样,也可以验证连接
>>> new_g.edges(form='all', order='eid', etype='plays') (tensor([0, 1]), tensor([0, 1]), tensor([0, 1])) >>> new_g2.edges(form='all', order='eid', etype='plays') (tensor([0, 2]), tensor([2, 3]), tensor([0, 1]))