igraph Tutorial


 

igraph Tutorial

In [25]:
#導入包
import igraph
from igraph import Graph,summary,plot
In [26]:
#查看安裝包的版本,Tutorial中版本為0.6的
igraph.__version__
Out[26]:
'0.7.1'
 

一、Creating a graph from scratch

In [27]:
g = Graph(1) #生成的graph是只有一個頂點的無向圖
In [28]:
g
Out[28]:
<igraph.Graph at 0x5c58048>
In [29]:
print g #U:無向的,1:1個頂點,0:0條邊
 
IGRAPH U--- 1 0 --
 

1) 添加頂點 add_vertices()

In [30]:
g.add_vertices(2) #添加兩個頂點
In [31]:
print g #輸出:目前有3個頂點
 
IGRAPH U--- 3 0 --
 

2) 添加邊 add_edges()

In [32]:
#igraph使用連續性的整數從0開始用於頂點的索引,用索引對來表示邊
#如下[(0,1),(1,2)]表示兩條邊,一個是第一個頂點和第二個頂點之間的邊,第二個表示第二個頂點和第三個頂點之間的邊
In [33]:
g.add_edges([(0,1),(1,2)]) #添加兩條邊
In [34]:
print g #輸出多了邊的數量及具體的邊
 
IGRAPH U--- 3 2 --
+ edges:
0--1 1--2
In [35]:
type(g.add_edges([(2,0)])) #add_edges方法返回值為NoneType,即不返回igraph對象,與0.6版本的不同,所以不能g.add_edges([2,0]).add_edges([1,2])
Out[35]:
NoneType
In [37]:
g.add_vertices(3) #增加3個頂點,此時頂點最大索引是5
g.add_edges([(2,3),(3,4),(4,5),(5,3)]) #增加四條邊
In [38]:
print g #輸出共有6個頂點,7條邊
 
IGRAPH U--- 6 7 --
+ edges:
0--1 1--2 0--2 2--3 3--4 4--5 3--5
 

3) 刪除頂點 delete_vertices() 刪除邊 delete_edges()

 

igraph的圖和邊的ID(索引)都是連續的,和列表索引類似,如果刪除其中的邊,后面的ID會自動更新,刪除頂點亦如此。更甚者,如果刪除了邊,頂點的ID也會變

In [39]:
print g
 
IGRAPH U--- 6 7 --
+ edges:
0--1 1--2 0--2 2--3 3--4 4--5 3--5
In [41]:
g.delete_vertices((2,3))
In [43]:
#刪除頂點ID為2和3的,剩余頂點ID為(0,1,4,5),同時會將涉及到的邊刪去(頂點都沒有了,邊自然也無用了),剩余邊有兩條[(0,1),(4,5)]
#而后,后面的頂點ID會自動補齊,即ID變為(0,1,2,3)(4變為2,5變為3),涉及的邊也要變更,則邊為[(0,1),(2,3)]
print g
 
IGRAPH U--- 4 2 --
+ edges:
0--1 2--3
In [47]:
g.add_vertices(2)
g.add_edges([(1,5),(3,5)])
In [48]:
print g
 
IGRAPH U--- 6 4 --
+ edges:
0--1 2--3 1--5 3--5
In [52]:
g.get_eid(1,5),g.get_eid(3,5)
Out[52]:
(2, 3)
In [53]:
g.delete_edges(2)
In [54]:
print g
 
IGRAPH U--- 6 3 --
+ edges:
0--1 2--3 3--5
In [56]:
g.get_eid(3,5)
Out[56]:
2
 

4) summary

 

summary輸出結果和str或者print出的結果類似,只是更加靈活些

 

有如下參數,具體可看官方文檔 graph, verbosity=0, width=78, edge_list_format=’auto’,max_rows=99999, print_graph_attributes=False,print_vertex_attributes=False, print_edge_attributes=False, full=False

In [61]:
summary(g) #默認情況下verbosity=1:只輸出head line,即只顯示一些匯總信息之類的
 
IGRAPH U--- 6 3 -- 
In [62]:
summary(g,verbosity=1)
 
IGRAPH U--- 6 3 -- 
+ edges:
0--1 2--3 3--5
In [67]:
summary(g, verbosity=1, print_graph_attributes=True, print_vertex_attributes=True, print_edge_attributes=True, full=True)
 
IGRAPH U--- 6 3 -- 
+ edges:
0--1 2--3 3--5
In [63]:
g.__str__()
Out[63]:
'IGRAPH U--- 6 3 --\n+ edges:\n0--1 2--3 3--5'
 

二、Generating graphs

 

igraph有很多生成器,主要分為兩大類:確定性的(deterministic)和隨機性的(stochastic)。前者如果每次同一個方法且參數值相同,則生成的圖相同,而后者則每次生成的圖是不同的。

In [75]:
#Tree:確定性的圖生成器
g_1 = Graph.Tree(127,2) #Tree :每個頂點有兩個孩子節點和一個父節點
g_2 = Graph.Tree(127,2)
In [76]:
print g_1
 
IGRAPH U--- 127 126 --
+ edges:
0--1 0--2 1--3 1--4 2--5 2--6 3--7 3--8 4--9 4--10 5--11 5--12 6--13 6--14
7--15 7--16 8--17 8--18 9--19 9--20 10--21 10--22 11--23 11--24 12--25 12--26
13--27 13--28 14--29 14--30 15--31 15--32 16--33 16--34 17--35 17--36 18--37
18--38 19--39 19--40 20--41 20--42 21--43 21--44 22--45 22--46 23--47 23--48
24--49 24--50 25--51 25--52 26--53 26--54 27--55 27--56 28--57 28--58 29--59
29--60 30--61 30--62 31--63 31--64 32--65 32--66 33--67 33--68 34--69 34--70
35--71 35--72 36--73 36--74 37--75 37--76 38--77 38--78 39--79 39--80 40--81
40--82 41--83 41--84 42--85 42--86 43--87 43--88 44--89 44--90 45--91 45--92
46--93 46--94 47--95 47--96 48--97 48--98 49--99 49--100 50--101 50--102
51--103 51--104 52--105 52--106 53--107 53--108 54--109 54--110 55--111
55--112 56--113 56--114 57--115 57--116 58--117 58--118 59--119 59--120
60--121 60--122 61--123 61--124 62--125 62--126
In [78]:
#GRG:隨機性的圖
g_3 = Graph.GRG(100,0.2) #GRG:geometric random graph
g_4 = Graph.GRG(100,0.2)
 

get_edgelist()

In [86]:
#獲取有頂點ID對組成的列表,即圖的邊的信息
#g_1.get_edgelist()
g_1.get_edgelist()[0:5]
Out[86]:
[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5)]
In [87]:
g_1.get_edgelist() == g_2.get_edgelist() #確定性的圖,每次生成的是一樣的
Out[87]:
True
In [88]:
g_3.get_edgelist() == g_4.get_edgelist() #隨機性的圖,每次生成的不一樣
Out[88]:
False
In [81]:
g_3 == g_4,g_1 == g_2
Out[81]:
(False, False)
 

isomorphic() 檢驗兩個Graph對象是否是同構的

In [89]:
g_1.isomorphic(g_2)
Out[89]:
True
In [90]:
g_3.isomorphic(g_4)
Out[90]:
False
 

三、Setting and retrieving attributes

In [91]:
#g_5是一個簡易的社交網絡圖,頂點代表人,邊代表關系
g_5 = Graph([(0,1),(0,2),(2,3),(3,4),(4,2),(2,5),(5,0),(6,3),(5,6)])
In [92]:
print g_5
 
IGRAPH U--- 7 9 --
+ edges:
0 -- 1 2 5     2 -- 0 3 4 5   4 -- 2 3       6 -- 3 5
1 -- 0         3 -- 2 4 6     5 -- 0 2 6
 

vs & es:Graph對象包含兩個比較特殊的成員vs,es,分別代表Graph對象的頂點序列和邊序列VertexSeq,EdgeSeq

In [96]:
g_5.vs,g_5.es
Out[96]:
(<igraph.VertexSeq at 0x5cad688>, <igraph.EdgeSeq at 0x5c5ceb8>)
 

可以將vs,es看作是個字典對象,進行屬性設置

In [97]:
g_5.vs['name']=['Alice','Bob','Claire','Dennis','Esther','Frank','Geprge']
In [98]:
g_5.vs['age']=[25,31,18,47,22,23,50]
In [99]:
g_5.vs['gender']=['f','m','f','m','f','m','m']
In [100]:
g_5.es['is_formal']=[False,False,True,True,True,False,True,False,False]
In [109]:
g_5.vs.attributes() #attributes()查看有哪些屬性
Out[109]:
['gender', 'age', 'name']
In [108]:
g_5.vs.get_attribute_values('age') #get_attribute_values(key)查看屬性有哪些值 
Out[108]:
[25, 31, 18, 47, 22, 23, 50]
In [101]:
print g_5
 
IGRAPH UN-- 7 9 --
+ attr: age (v), gender (v), name (v), is_formal (e)
+ edges (vertex names):
 Alice -- Bob, Claire, Frank
   Bob -- Alice
Claire -- Alice, Dennis, Esther, Frank
Dennis -- Claire, Esther, Geprge
Esther -- Claire, Dennis
 Frank -- Alice, Claire, Geprge
Geprge -- Dennis, Frank
 

也可以將vs,es看作是列表對象,通過索引查看單個邊或頂點對象

In [110]:
g_5.vs[0]
Out[110]:
igraph.Vertex(<igraph.Graph object at 0x0000000005C58138>,0,{'gender': 'f', 'age': 25, 'name': 'Alice'})
In [112]:
g_5.vs[0].attributes()
Out[112]:
{'age': 25, 'gender': 'f', 'name': 'Alice'}
In [114]:
g_5.es[2]
Out[114]:
igraph.Edge(<igraph.Graph object at 0x0000000005C58138>, 2, {'is_formal': True})
In [115]:
g_5.es[2].attributes()
Out[115]:
{'is_formal': True}
In [126]:
g_5.es[2]['is_formal']=False #對單個邊或頂點對象可通過字典形式修改屬性值
In [127]:
g_5.es[2].attributes()
Out[127]:
{'is_formal': False}
 

Vertex,Edge對象一些常見的屬性

In [144]:
#Edge
g_5.es[2]
Out[144]:
igraph.Edge(<igraph.Graph object at 0x0000000005C58138>, 2, {'is_formal': False})
In [139]:
g_5.es[2].source #邊的源頂點
Out[139]:
2
In [140]:
g_5.es[2].target #邊的目標頂點
Out[140]:
3
In [141]:
g_5.es[2].tuple #返回邊的源和目標頂點,以元組形式呈現
Out[141]:
(2, 3)
In [143]:
g_5.es[2].attributes() #以字典形式返回該Vertex對象的屬性
Out[143]:
{'is_formal': False}
In [148]:
g_5.es[2].index #返回邊的ID
Out[148]:
2
In [145]:
#Vertex 沒有tuple,source,target屬性
g_5.vs[1]
Out[145]:
igraph.Vertex(<igraph.Graph object at 0x0000000005C58138>,1,{'gender': 'm', 'age': 31, 'name': 'Bob'})
In [146]:
g_5.vs[1].attributes()
Out[146]:
{'age': 31, 'gender': 'm', 'name': 'Bob'}
In [147]:
g_5.vs[1].index #返回頂點對象的ID
Out[147]:
1
In [149]:
#修改屬性
g_5.vs[3]['foo'] = 'bar'
In [150]:
g_5.vs['foo']
Out[150]:
[None, None, None, 'bar', None, None, None]
In [151]:
del g_5.vs['foo'] #可以使用del對屬性進行刪除
In [152]:
g_5.vs['foo']
 
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-152-8a5b1ed9423a> in <module>()
----> 1g_5.vs['foo']

KeyError: 'Attribute does not exist'
 

四、Structural properties of graphs

 

如下表格總結參考 http://blog.csdn.net/u010289316/article/details/51645064

指標名稱 概念 比較 實際應用 對應iGraph中的方法
點度中心度 在某個點上,有多少條線 強調某點單獨的價值 ★作為基本點的描述 Graph.degree()
接近中心度 該點與網絡中其他點距離之和的倒數,越大說明越在中心,越能夠很快到達其他點 強調點在網絡的價值,越大,越在中心 ★★基本描述,用戶價值 Graph.closeness()
中間中心度 代表最短距離是否都經過該點,如果都經過說明這個點很重要,其中包括線的中心度 強調點在其他點之間調節能力,控制能力指數,中介調節效應 ★★推薦算法,用戶的控制力 Graph.betweenness()
特征向量中心度 根據相鄰點的重要性來衡量該點的價值。首先計算鄰接矩陣,然后計算鄰接矩陣的特征向量。 強調點在網絡的價值,並且比接近中心度厲害的是,點價值是根據近鄰點來決定的 ★★★推薦算法,用戶潛在價值 Graph.evcent()
 

1) Graph.degree() 返回圖的度(點度中心度)

In [158]:
g_5.vs.__str__()
Out[158]:
'<igraph.VertexSeq object at 0x0000000005CC0F48>'
In [163]:
g_5.get_edgelist()
Out[163]:
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
In [176]:
#degree:求頂點的度,即有多少個邊包含該頂點,參數中傳入一個列表,可以返回指定頂點的度
g_5.degree(), g_5.degree([0,2,4])
Out[176]:
([3, 1, 4, 3, 2, 3, 2], [3, 4, 2])
In [177]:
#入度和出度
g_5.degree(mode='in'), g_5.degree(mode='out') 
Out[177]:
([3, 1, 4, 3, 2, 3, 2], [3, 1, 4, 3, 2, 3, 2])
In [178]:
g_5.indegree(),g_5.outdegree()
Out[178]:
([3, 1, 4, 3, 2, 3, 2], [3, 1, 4, 3, 2, 3, 2])
 

2) Graph.closeness() 返回圖對象的接近中心度

In [183]:
g_5.closeness()
Out[183]:
[0.6666666666666666,
 0.42857142857142855,
 0.75,
 0.6,
 0.5454545454545454,
 0.6666666666666666,
 0.5454545454545454]
 

3) Graph.edge_betweenness() 返回邊的中間中心度、Graph.betweenness() 返回頂點的中間中心度

In [185]:
g_5.edge_betweenness()
Out[185]:
[6.0, 6.0, 4.0, 2.0, 4.0, 3.0, 4.0, 3.0, 4.0]
In [186]:
g_5.get_edgelist()
Out[186]:
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
In [187]:
ebs = g_5.edge_betweenness()
max_eb = max(ebs)
In [188]:
max_eb
Out[188]:
6.0
In [191]:
# 返回中心度最大的邊
[g.es[idx].tuple for idx,eb in enumerate(ebs) if eb==max_eb]
Out[191]:
[(0, 1), (2, 3)]
In [190]:
g_5.betweenness()
Out[190]:
[5.0, 0.0, 5.5, 1.5, 0.0, 2.5, 0.5]
 

4) Graph.evcent():點的特征向量中心度

In [194]:
g_5.evcent()
Out[194]:
[0.7111995450108003,
 0.24860112203602627,
 1.0,
 0.7513988779639744,
 0.6122047310756776,
 0.7860026990612522,
 0.5374015770252261]
In [195]:
plot(g_5)
Out[195]:
 
 

五、Querying vertices and edges based on attributes

In [198]:
g_5.degree(), g_5.maxdegree()
Out[198]:
([3, 1, 4, 3, 2, 3, 2], 4)
In [199]:
g_5.vs.select(_degree = g_5.maxdegree())['name']
Out[199]:
['Claire']
In [202]:
g_5.vs.select(_degree = g_5.maxdegree())
Out[202]:
<igraph.VertexSeq at 0x5cabef8>
 

select(self, *args, **kwds) 可以傳位置參數和關鍵字參數

 

1)參數為位置參數

In [203]:
#若第一個位置參數為None,返回一個空的序列
seq = g.vs.select(None)
In [204]:
len(seq)
Out[204]:
0
In [207]:
#若第一個位置參數為可調用對象(函數,方法,或者類似函數可調用的對象),若返回結果為True,則包含在返回序列中
graph = Graph.Full(10)
In [208]:
print graph
 
IGRAPH U--- 10 45 --
+ edges:
 0 --  1  2  3  4  5  6  7  8  9    5 --  0  1  2  3  4  6  7  8  9
 1 --  0  2  3  4  5  6  7  8  9    6 --  0  1  2  3  4  5  7  8  9
 2 --  0  1  3  4  5  6  7  8  9    7 --  0  1  2  3  4  5  6  8  9
 3 --  0  1  2  4  5  6  7  8  9    8 --  0  1  2  3  4  5  6  7  9
 4 --  0  1  2  3  5  6  7  8  9    9 --  0  1  2  3  4  5  6  7  8
In [209]:
only_odd_vertices = graph.vs.select(lambda vertex: vertex.index % 2 ==1)
In [210]:
len(only_odd_vertices)
Out[210]:
5
In [222]:
#若參數是可迭代的對象(列表,生成器,其他可迭代對象等),該對象必須返回整數序列,vertex的ID與返回的整數序列如有匹配上的,則包含在返回的序列中
seq = graph.vs.select([2,3,7])
In [223]:
len(seq)
Out[223]:
3
In [224]:
[v.index for v in seq]
Out[224]:
[2, 3, 7]
In [232]:
seq = seq.select([0,2]) #調用select的對象可以不必是Graph對象的完整的VexSeq
In [226]:
[v.index for v in seq]
Out[226]:
[2, 7]
In [233]:
seq = graph.vs.select([2,3,7,'foo',4.5]) #只能是范圍內的整數,字符串,浮點數會跳過,超過范圍的整數,則報錯
In [234]:
len(seq)
Out[234]:
3
In [240]:
#若第一個位置參數為整數,則后面的參數也必須為整數,相當於傳了一個整數類型的list
seq = graph.vs.select(2,3,7)
In [241]:
len(seq)
Out[241]:
3
 

2) 關鍵字參數

 

用來過濾屬性或者圖的結構性質,關鍵字包含兩部分,一部分是屬性或者結構性質的名字,另一部分過濾的操作符,后者可省略,此時默認為等於。因Python語法限制,參數中出現的操作符只能有=,不能出現>,<,in等。如下是可能的關鍵字:

 
Keyword argument Meaning
name_eq 屬性/性質的值必須 等於 關鍵字參數的值
name_ne ......不等於......
name_lt ......小於......
name_le ......小於等於......
name_gt ......大於......
name_ge ......大於等於......
name_in ......包含......,此時參數必須是一個序列
name_notin ......不包含......,此時參數必須是一個序列
In [243]:
print g_5
 
IGRAPH UN-- 7 9 --
+ attr: age (v), gender (v), name (v), is_formal (e)
+ edges (vertex names):
 Alice -- Bob, Claire, Frank
   Bob -- Alice
Claire -- Alice, Dennis, Esther, Frank
Dennis -- Claire, Esther, Geprge
Esther -- Claire, Dennis
 Frank -- Alice, Claire, Geprge
Geprge -- Dennis, Frank
In [244]:
g_5.vs['age']
Out[244]:
[25, 31, 18, 47, 22, 23, 50]
In [250]:
seq_lt = g_5.vs.select(age_lt=29) # 過濾屬性age的值小於29的
#seq_lt = g_5.vs(age_lt=29) # 也可把select省去
[v.index for v in seq_lt]
Out[250]:
[0, 2, 4, 5]
 

若屬性和結構性質的重名了,會出現歧義,此時如果關鍵字指的是結構性質需要在前面加_,即_name。否則會認為是屬性名字

In [252]:
g_5.get_edgelist()
Out[252]:
[(0, 1), (0, 2), (2, 3), (3, 4), (2, 4), (2, 5), (0, 5), (3, 6), (5, 6)]
In [253]:
g_5.degree()
Out[253]:
[3, 1, 4, 3, 2, 3, 2]
In [256]:
seq_stru = g_5.vs(_degree_gt=2)
[v.index for v in seq_stru]
Out[256]:
[0, 2, 3, 5]
In [258]:
seq_stru = g_5.vs(degree_gt=2) #沒有degree屬性,報錯
[v.index for v in seq_stru]
 
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-258-b126822cd4e0> in <module>()
----> 1seq_stru = g_5.vs(degree_gt=2) #沒有degree屬性,報錯
      2 [v.index for v in seq_stru]

C:\Anaconda2\lib\site-packages\igraph\__init__.pyc in __call__(self, *args, **kwds)
   3511         This method simply passes all its arguments to L{VertexSeq.select()}.
   3512         """
-> 3513return self.select(*args, **kwds)
   3514 
   3515 ##############################################################

C:\Anaconda2\lib\site-packages\igraph\__init__.pyc in select(self, *args, **kwds)
   3500                 values = getattr(vs.graph, attr[1:])(vs)
   3501             else:
-> 3502values = vs[attr]
   3503             filtered_idxs=[i for i, v in enumerate(values) if func(v, value)]
   3504             vs = vs.select(filtered_idxs)

KeyError: 'Attribute does not exist'
In [259]:
[vs.degree() for vs in g_5.vs]
Out[259]:
[3, 1, 4, 3, 2, 3, 2]
 

六、Layouts and plotting

 

1) 有很多種類的布局,如下為部分:

 
方法名 縮略名 算法描述
layout_circle circular 確定性布局,將頂點放在圓上
layout_drl drl 采用Distributed Recursive Layout算法,適用於比較大的圖
layout_fruchterman_reingold fr 采用力引導布局的FR(Fruchterman-Reingold)算法
layout_kamada_kawai kk 采用力導向布局的KK(Kamada-Kawai)算法
layout_random random 圖的頂點隨機放置
layout_reingold_tilford rt,tree 大型樹拓撲結構,緊湊分層的展示數據結構
 

可通過兩種方式使用:1 將縮略名作為參數傳入layout()方法中,2 直接調用方法名

In [356]:
layout = g_5.layout('circular')
#layout = g_5.layout_circle()
plot(g_5,layout=layout)
Out[356]:
 
 

2) Drawing a Graph

In [357]:
layout = g_5.layout('kk')
plot(g_5,layout = layout)
Out[357]:
 
In [355]:
#為頂點加標簽,用顏色區別gender屬性,頂點標簽默認使用頂點的label屬性,頂點顏色默認使用color屬性
In [358]:
g_5.vs['label'] = g_5.vs['name']
In [359]:
color_dict = {'m':'blue','f':'pink'}
g_5.vs['color'] = [color_dict[gender] for gender in g_5.vs['gender']]
In [364]:
plot(g_5,layout=layout,bbox=(300,300),margin=20)
Out[364]:
 
In [367]:
# 除了利用label,color屬性來畫圖外,還可以在plot傳入關鍵字鍵值對來進行設定
color_dict = {'m':'black','f':'white'}
plot(g_5,layout=layout,vertex_color=[color_dict[gender] for gender in g_5.vs['gender']],bbox=(300,300))
Out[367]:
 
In [368]:
#可以將圖的樣式屬性放在字典中,並通過**dict_style形式傳入plot即可
visual_style = {}
visual_style['vertex_size'] = 20
visual_style['vertex_color'] = [color_dict[gender] for gender in g_5.vs['gender']]
visual_style['vertex_label'] = g_5.vs['name']
visual_style['edge_width'] = [1 + 2 * int(is_formal) for is_formal in g_5.es['is_formal']]
visual_style['layout'] = layout
visual_style['bbox'] = (300,300)
visual_style['margin'] = 20
plot(g_5,**visual_style)
Out[368]:
 
 

3)保存Graph

In [369]:
# 可以保存為文件PDF,PNG等格式
plot(g_5,'social_network.pdf',**visual_style)
Out[369]:
 
In [ ]:
 


免責聲明!

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



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