有許多方法可以構造DGLGraph。文檔中建議使用的方法有四種,分別如下:
① 使用兩個數組,分別存儲源節點和目標節點對象 (數組類型可以是numpy 也可以是 tensor)。
② scipy 中的稀疏矩陣(),表示要構造的圖的鄰接矩陣。
③ networkx 的圖對象(DGLGraph 和 networkx 可以互轉)。
④ 整數對形式的邊列表。
下面分別展示了用四種方法建圖:
import networkx as nx import dgl import torch import numpy as np import scipy.sparse as spp import matplotlib.pyplot as plt ## 方式1: 使用兩個節點數組構造圖 u = torch.tensor([0,0,0,0,0]) v = torch.tensor([1,2,3,4,5]) g1 = dgl.DGLGraph((u,v)) # 如果數組之一是標量,該值自動廣播以匹配另一個數組的長度,稱為“邊緣廣播”的功能。 g1 = dgl.DGLGraph((0,v)) ## 方式2: 使用稀疏矩陣進行構造 adj = spp.coo_matrix((np.ones(len(u)), (u.numpy(), v.numpy()))) ## 傳入的參數(data, (row, col)) g2 = dgl.DGLGraph(adj) ## 方式3: 使用networkx g_nx =nx.petersen_graph() g3 = dgl.DGLGraph(g_nx) ## 方式4:加邊 (沒有上面的方法高效) g4 = dgl.DGLGraph() g4.add_nodes(10) # 添加節點數量 該方法第二個參數是添加每個節點的特征。 ## 加入邊 for i in range(1,5): # 一條條邊添加 g4.add_edge(i,0) src = list(range(5,8));dst = [0]*3 # 使用list批量添加 g4.add_edges(src, dst) src = torch.tensor([8,9]);dst = torch.tensor([0,0]) # 使用list批量添加 g4.add_edges(src, dst) plt.subplot(221) nx.draw(g1.to_networkx(), with_labels=True) plt.subplot(222) nx.draw(g2.to_networkx(), with_labels=True) plt.subplot(223) nx.draw(g3.to_networkx(), with_labels=True) plt.subplot(224) nx.draw(g4.to_networkx(), with_labels=True) plt.show()
為DGL圖中的節點和邊分配特征: 這些特征表示為名稱(字符串)和張量的字典,稱為字段。以下代碼段為每個節點分配一個向量(len = 3)。
import dgl import torch import networkx as nx import matplotlib.pyplot as plt g = dgl.DGLGraph() g.add_nodes(10) for i in range(1,10): g.add_edge(i,0) ## 為節點分配特征 x = torch.randn(10, 3) g.ndata['x'] = x g.ndata['x'][0] = torch.zeros(1,3) g.ndata['x'][[0,1,2]] = torch.zeros(3,3) g.ndata['x'][torch.tensor([0, 1, 2])] = torch.randn((3, 3)) ## 為邊分配特征 g.edata['w'] = torch.randn(9, 2) g.edata['w'][1] = torch.randn(1, 2) g.edata['w'][[0, 1, 2]] = torch.zeros(3, 2) g.edata['w'][torch.tensor([0, 1, 2])] = torch.zeros(3, 2) g.edata['w'][g.edge_id(1, 0)] = torch.ones(1, 2) # edge 1 -> 0 g.edata['w'][g.edge_ids([1, 2, 3], [0, 0, 0])] = torch.ones(3, 2) # edges [1, 2, 3] -> 0 # Use edge broadcasting whenever applicable. g.edata['w'][g.edge_ids([1, 2, 3], 0)] = torch.ones(3, 2) # edges [1, 2, 3] -> 0 print(g.node_attr_schemes()) ## 查看節點屬性
移除節點特征和邊特征:
g.ndata.pop('x') g.edata.pop('w')
對於擁有節點擁有多條邊multigraphs:
import dgl import torch import networkx as nx import matplotlib.pyplot as plt g = dgl.DGLGraph() g.add_nodes(10) for i in range(1,10): g.add_edge(i,0) ## 為節點分配特征 x = torch.randn(10, 3) g.ndata['x'] = x g.ndata['x'][0] = torch.zeros(1,3) g.ndata['x'][[0,1,2]] = torch.zeros(3,3) g.ndata['x'][torch.tensor([0, 1, 2])] = torch.randn((3, 3)) ## 為邊分配特征 g.edata['w'] = torch.randn(9, 2) g.edata['w'][1] = torch.randn(1, 2) g.edata['w'][[0, 1, 2]] = torch.zeros(3, 2) g.edata['w'][torch.tensor([0, 1, 2])] = torch.zeros(3, 2) g.edata['w'][g.edge_id(1, 0)] = torch.ones(1, 2) # edge 1 -> 0 g.edata['w'][g.edge_ids([1, 2, 3], [0, 0, 0])] = torch.ones(3, 2) # edges [1, 2, 3] -> 0 # Use edge broadcasting whenever applicable. g.edata['w'][g.edge_ids([1, 2, 3], 0)] = torch.ones(3, 2) # edges [1, 2, 3] -> 0 print(g.node_attr_schemes()) ## 查看節點屬性 g_multi = dgl.DGLGraph() g_multi.add_nodes(10) g_multi.ndata['x'] = torch.randn(10, 2) g_multi.add_edges(list(range(1, 10)), 0) g_multi.add_edge(1, 0) # two edges on 1->0 g_multi.edata['w'] = torch.randn(10, 2) print(g_multi.edges()) ## 有重邊的話沒辦法通過 (u,v)定位,需要使用edge_id來獲取 eid_10 = g_multi.edge_id(1, 0, return_array=True) print(eid_10) g_multi.edges[eid_10].data['w'] = torch.ones(len(eid_10), 2) print(g_multi.edata['w'])