DGL官方教程--API--dgl.DGLGraph

参考:https://docs.dgl.ai/en/latest/api/python/graph.html#

class dgl.DGLGraph(graph_data=None, node_frame=None, edge_frame=None, multigraph=None,
 readonly=False, sort_csr=False, batch_num_nodes=None, batch_num_edges=None, parent=None)

基本的图的类。

图的类存储节点,边及其特征。

DGL图始终是有方向的。可以使用两个双向边来表示无向图。

节点由从零开始的连续整数标识。

当给图添加边时,可以通过两个端点(u,v)或分配的整数id来指定边。边的ID是顺序自动分配,即,添加的第一个边的ID为0,第二个边的ID为1,依此类推。

节点和边的特征存储方式是:以“特征名”为键和以“特征数据”为值的字典(以张量表示)。

DGL图形接受多种格式的图形数据:

  • NetworkX图,
  • scipy 矩阵
  • DGLGraph。

如果输入图数据是DGLGraph,则构造的DGLGraph仅包含其图索引。

参数:
  • graph_data (graph data, optional)–用于初始化图形的数据。
  • node_frame (FrameRef, optional)–节点特征存储。
  • edge_frame (FrameRef, optional)–边缘特征存储。
  • multigraph (booloptional)–图形是否为多图数据。如果不存在,则将通过扫描整个图形来确定该标志。(默认值:None)
  • readonly (booloptional)–图形结构是否为只读(默认:False)。

例子

创建一个没有节点和边的空图。

>>> G = dgl.DGLGraph()

G可以通过几种方式生长。

节点:

添加N个节点:

>>> G.add_nodes(10)  # 10 isolated nodes are added

边:

一次添加一条边,

>>> G.add_edge(0, 1)

或多个边,

>>> G.add_edges([1, 2, 3], [3, 4, 5])  # three edges: 1->3, 2->4, 3->5

或从同一节点开始的多个边,

>>> G.add_edges(4, [7, 8, 9])  # three edges: 4->7, 4->8, 4->9

或指向同一节点的多个边

>>> G.add_edges([2, 6, 8], 5)  # three edges: 2->5, 6->5, 8->5

或使用张量类型的多个边

在这里,使用pytorch框架进行演示,一般可以适用于其他变化较小的框架。(例如,替换 torch.tensor为mxnet.ndarray)。

>>> import torch as th
>>> G.add_edges(th.tensor([3, 4, 5]), 1)  # three edges: 3->1, 4->1, 5->1

注意:DGLGraph不支持删除节点和边。

特征:

节点和边都可以具有特征数据。特征数据存储为键/值对。键必须是可选的,而值必须是张量类型。特征在第一维度上被批次化。(这里有点没懂。。。)

使用G.ndata获取/设置所有节点的特征

>>> G = dgl.DGLGraph()
>>> G.add_nodes(3)
>>> G.ndata['x'] = th.zeros((3, 5))  # init 3 nodes with zero vector(len=5)
>>> G.ndata
{'x' : tensor([[0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]])}
 

使用G.nodes获取/设置某些节点的特征

>>> G.nodes[[0, 2]].data['x'] = th.ones((2, 5))
>>> G.ndata
{'x' : tensor([[1., 1., 1., 1., 1.],
               [0., 0., 0., 0., 0.],
               [1., 1., 1., 1., 1.]])}

同样,使用G.edata和G.edges获取/设置边的特征。

>>> G.add_edges([0, 1], 2)  # 0->2, 1->2
>>> G.edata['y'] = th.zeros((2, 4))  # init 2 edges with zero vector(len=4)
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
               [0., 0., 0., 0.]])}
>>> G.edges[1, 2].data['y'] = th.ones((1, 4))
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
               [1., 1., 1., 1.]])}

 

注意,为每个边都分配了一个唯一的ID,该ID等于其添加顺序。因此,边(1-> 2)的ID为1。DGL支持直接使用边的ID访问边的特征。

>>> G.edges[0].data['y'] += 2.
>>> G.edata
{'y' : tensor([[2., 2., 2., 2.],
               [1., 1., 1., 1.]])}

 

讯息传递:

更新节点特征的一个常见操作是消息传递,其中源结点通过边向目的结点发送消息。在DGLGraph中,我们可以使用send()recv()

在下面的示例中,源节点将节点特征做加1操作后,作为消息,并将消息发送到目标。

>>> #定义发送消息的函数。
>>> def send_source(edges): return {'m': edges.src['x'] + 1}
>>> #将这个函数定义为默认消息函数。
>>> G.register_message_func(send_source)
>>> #通过所有边 发送信息。
>>> G.send(G.edges())

 

就像您需要进入邮箱以检索邮件一样,目标节点也需要接收消息并可能更新其特征。

>>> #定义一个用于总结接收到的消息并替换原始特征的函数。
>>> def simple_reduce(nodes): return {'x': nodes.mailbox['m'].sum(1)}
>>> #定义为默认消息约简函数。
>>> G.register_reduce_func(simple_reduce)
>>> #所有现有边都以节点2作为目标。
>>> #节点2接收消息并更新其特征。
>>> G.recv(v=2)
>>> G.ndata
{'x': tensor([[1., 1., 1., 1., 1.],
              [0., 0., 0., 0., 0.],
              [3., 3., 3., 3., 3.]])} # 3 = (1 + 1) + (0 + 1)

 

有关消息传递的更多示例,请阅读我们的教程。

PS:下面函数API建议看官方的文档,有源码实现

网址:https://docs.dgl.ai/en/latest/api/python/graph.html#

添加节点和边

DGLGraph.add_nodes(* args,** kwargs)  
DGLGraph.add_edge(* args,** kwargs)  
DGLGraph.add_edges(* args,** kwargs)  
DGLGraph.clear() 从图中删除所有节点和边线及其特征。

查询图结构

DGLGraph.number_of_nodes() 返回图中的节点数。
DGLGraph.number_of_edges() 返回图中的边数。
DGLGraph.__len__() 返回图中的节点数。
DGLGraph.is_multigraph 如果图形是多图,则为True,否则为False。
DGLGraph.has_node(vid) 如果图形包含节点vid,则返回True 。
DGLGraph.has_nodes(vids) 给定节点ID数组,返回一个包含0-1的数组a。
DGLGraph.__contains__(vid) 如果图形包含节点vid,则返回True 。
DGLGraph.has_edge_between(u,v) 如果边(u,v)在图中,则返回True。
DGLGraph.has_edges_between(u,v) 给定源节点ID数组u和目标节点ID数组v,返回一个包含0-1的数组a。
DGLGraph.predecessors(v) 返回图中的节点v的前继结点。
DGLGraph.successors(v) 返回图中的节点v的后继结点。
DGLGraph.edge_id(u,v [,force_multi]) 返回源节点u和目标节点v之间的边的ID或边的ID数组。
DGLGraph.edge_ids(u,v [,force_multi]) 返回源节点数组u和目标节点数组v之间的所有边的ID 。
DGLGraph.find_edges(eid) 给定一个边的ID数组,返回源和目标节点ID数组s和d。
DGLGraph.in_edges(v[, form]) 返回节点的入边。
DGLGraph.out_edges(v[, form]) 返回节点的出边。
DGLGraph.all_edges([form, order]) 返回所有边。
DGLGraph.in_degree(v) 返回节点v的入度。
DGLGraph.in_degrees([v]) 返回节点数组v的入度数组。
DGLGraph.out_degree(v) 返回节点v的出度。
DGLGraph.out_degrees([v]) 返回节点数组v的出度数组。

查询批处理汇总

DGLGraph.batch_size 此批次中的图形数。
DGLGraph.batch_num_nodes 此批次中每个图的节点数。
DGLGraph.batch_num_edges 此批处理中每个图的边数。

查询子图/父图所属信息

DGLGraph.parent 如果当前图是父图的子图,则返回其父图,否则返回None。

删除节点和边

DGLGraph.remove_nodes(* args,** kwargs)  
DGLGraph.remove_edges(* args,** kwargs)  

改造图

DGLGraph.subgraph(nodes) 返回在给定节点上导出的子图。
DGLGraph.subgraphs(nodes) 返回一个子图列表,每个子图在列表中相应的给定节点中诱导。
DGLGraph.edge_subgraph(edges[,preserve_nodes]) 返回在给定边上导出的子图。
DGLGraph.line_graph([backtracking, shared]) 返回此图的折线图。
DGLGraph.reverse([share_ndata,share_edata]) 返回此图的反面。
DGLGraph.readonly([readonly_state]) 设置此图的只读状态。
DGLGraph.flatten() 删除该图的所有批处理信息,并将当前图视为一个独立图,而不是一个批处理图。
DGLGraph.detach_parent() 从其父级分离当前图,并将当前图视为独立图而不是子图。

从/转换为其他格式

DGLGraph.to_networkx([node_attrs,edge_attrs]) 转换为networkx图。
DGLGraph.from_networkx(nx_graph [,…]) 从networkx图转换。
DGLGraph.from_scipy_sparse_matrix(spmat [,…]) 从scipy稀疏矩阵转换。
DGLGraph.adjacency_matrix([transpose, ctx]) 返回此图的邻接矩阵表示。
DGLGraph.adjacency_matrix_scipy([transpose, …]) 返回此图的scipy邻接矩阵表示形式。
DGLGraph.incidence_matrix(typestr[, ctx]) 返回此图的关联矩阵表示。

使用节点/边缘特征

DGLGraph.nodes 返回可用于设置/获取要素数据的节点视图。
DGLGraph.edges 返回可用于设置/获取要素数据的边视图。
DGLGraph.ndata 返回所有节点的数据视图。
DGLGraph.edata 返回所有边的数据视图。
DGLGraph.node_attr_schemes() 返回节点特征方案。
DGLGraph.edge_attr_schemes() 返回边缘特征方案。
DGLGraph.set_n_initializer(initializer[, field]) 为空节点功能设置初始化程序。
DGLGraph.set_e_initializer(initializer[, field]) 为空边缘特征设置初始值设定项。
DGLGraph.local_var() 返回可以在局部函数范围内使用的图形对象。
DGLGraph.local_scope() 输入此图的本地范围上下文。

使用DGLGraph计算

DGLGraph.register_message_func(func) 注册全局消息功能。
DGLGraph.register_reduce_func(func) 注册全局消息减少功能。
DGLGraph.register_apply_node_func(func) 注册全局节点应用功能。
DGLGraph.register_apply_edge_func(func) 注册全局边缘应用功能。
DGLGraph.apply_nodes([func,v,inplace]) 在节点上应用功能以更新其功能。
DGLGraph.apply_edges([func, edges, inplace]) 在边缘应用功能以更新其功能。
DGLGraph.group_apply_edges(group_by,func [,…]) 按节点对边缘进行分组,然后将功能应用到分组的边缘上
DGLGraph.send([edges,message_func]) 沿给定的边缘发送消息。
DGLGraph.recv([v,reduce_func,…]) 接收和减少传入消息并更新节点的功能 vv。
DGLGraph.send_and_recv(edges[, …]) 沿边缘发送消息,并让目的地接收它们。
DGLGraph.pull(v [,message_func,…]) 从节点的前任提取消息,然后更新其功能。
DGLGraph.push(u [,message_func,…]) 将消息从节点发送到其后继节点并进行更新。
DGLGraph.update_all([message_func,...]) 通过所有边缘发送消息并更新所有节点。
DGLGraph.prop_nodes(nodes_generator [,…]) 通过pull()在节点上触发,使用图遍历传播消息。
DGLGraph.prop_edges(edges_generator [,…]) 通过send_and_recv()边沿触发使用图遍历传播消息。
DGLGraph.filter_nodes(predicate[, nodes]) 返回满足给定谓词的节点ID的张量。
DGLGraph.filter_edges(predicate[, edges]) 返回满足给定谓词的边缘ID的张量。
DGLGraph.to(ctx) 将ndata和edata都移动到目标模式(cpu / gpu)与框架无关

批处理和Unbatch 

batch(graph_list [,node_attrs,edge_attrs]) 批处理的一个集合DGLGraph并返回一个DGLGraph独立于的批处理对象,graph_list以便可以同时对一批图形执行消息传递和读出,返回图形的批大小为的长度graph_list
unbatch(graph) 返回此批处理中的图形列表。

子图和父图之间的映射

DGLGraph.parent_nid 获取父节点ID。
DGLGraph.parent_eid 获取父边缘ID。
DGLGraph.map_to_subgraph_nid(parent_vids) 将父图中的节点ID映射到子图中的节点ID。

在子图和父图之间同步功能

DGLGraph.copy_from_parent() 从父图中复制节点/边缘特征。
DGLGraph.copy_to_parent([inplace]) 将节点/边特征写入父图。

你可能感兴趣的:(DGL库笔记)