DGL學習(二): 使用DGL構造圖


有許多方法可以構造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'])

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM