1. 程式人生 > >Python 學習 第十六篇:networkx

Python 學習 第十六篇:networkx

字符類 tla 需要 ctr gre bic 訪問 ref plt

networkx是Python的一個包,用於構建和操作復雜的圖結構,提供分析圖的算法。圖是由頂點、邊和可選的屬性構成的數據結構,頂點表示數據,邊是由兩個頂點唯一確定的,表示兩個頂點之間的關系。頂點和邊也可以擁有更多的屬性,以存儲更多的信息。

對於networkx創建的無向圖,允許一條邊的兩個頂點是相同的,即允許出現自循環,但是不允許兩個頂點之間存在多條邊,即出現平行邊。

邊和頂點都可以有自定義的屬性,屬性稱作邊和頂點的數據,每一個屬性都是一個Key:Value對。

一,創建圖

在創建圖之前,需要導入networkx模塊,通常設置別名為nx;如果創建的圖中,頂點之間的邊沒有方向,那麽該圖稱作無向圖。在創建圖時,可以通過help(g)來獲得圖的幫助文檔。

import networkx as nx

g=nx.Graph()#創建空的無向圖
g=nx.DiGraph()#創建空的有向圖

二,圖的頂點

圖中的每一個頂點Node都有一個關鍵的ID屬性,用於唯一標識一個節點,ID屬性可以整數或字符類型;頂點除了ID屬性之外,還可以自定義其他的屬性。

1,向圖中增加頂點

在向圖中增加頂點時,可以一次增加一個頂點,也可以一次性增加多個頂點,頂點的ID屬性是必需的。在添加頂點之後,可以通過g.nodes()函數獲得圖的所有頂點的視圖,返回的實際上NodeView對象;如果為g.nodes(data=True)的data參數設置為true,那麽返回的是NodeDataView對象,該對象不僅包含每個頂點的ID屬性,還包括頂點的其他屬性。

g.add_node(1)
g.add_nodes_from([2,3,4])
g.nodes()
#NodeView((1, 2,3,4))

在向圖中添加頂點時,除ID屬性之外,也可以向頂點中增加自定義的屬性,例如,名稱屬性,權重屬性:

>>> g.add_node(1,name=n1,weight=1)
>>> g.add_node(2,name=n2,weight=1.2)

2,查看頂點的屬性

通過屬性_node獲得圖的所有頂點和屬性的信息,_node屬性返回的是一個字典結構,字典的Key屬性是頂點的ID屬性,Value屬性是頂點的其他屬性構成的一個字典。

>>> g._node
{1: {name: n1, weight: 1}, 2: {name: n2, weight: 1.2}, 3: {}, 4: {}}
>>>g.nodes(data=True)

可以通過頂點的ID屬性來查看頂點的其他屬性:

>>> g.node[1]
{name: n1, weight: 1}
>>> g.node[1][name]
n1 new

通過g.nodes(),按照特定的條件來查看頂點:

 >>> list(g.nodes(data=True))
 [(1, {time: 5pm}), (3, {time: 2pm})]

3,刪除頂點

通過remove函數刪除圖的頂點,由於頂點的ID屬性能夠唯一標識一個頂點,通常刪除頂點都需要通過傳遞ID屬性作為參數。

g.remove_node(node_ID)
g.remove_nodes_from(nodes_list)

4,更新頂點

更新圖的頂點,有兩種方式,第一種方式使用字典結構的_update函數,第二種方式是通過索引來設置新值:

>>> g._node[1].update({name:n1 new})
>>> g.node[1][name]=n1 new
{1: {name: n1 new, weight: 1}, 2: {name: n2, weight: 1.2}, 3: {}, 4: {}}

5,刪除頂點的屬性

使用del命令刪除頂點的屬性

del g.nodes[1][room] 

6,檢查是否存在頂點

檢查一個頂點是否存在於圖中,可以使用 n in g方式來判斷,也可以使用函數:

g.has_node(n)

三,圖的邊

圖的邊用於表示兩個頂點之間的關系,因此,邊是由兩個頂點唯一確定的。為了表示復雜的關系,通常會為邊增加一個權重weight屬性;為了表示關系的類型,也會設置為邊設置一個關系屬性。

1,向圖中增加邊

邊是由對應頂點的名稱構成的,例如,頂點2和3之間有一條邊,記作e=(2,3),通過add_edge(node1,node2)向圖中添加一條邊,也可以通過add_edges_from(list)向圖中添加多條邊;在添加邊時,如果頂點不存在,那麽networkx會自動把相應的頂點加入到圖中。

g.add_edge(2,3)
g.add_edges_from([(1,2),(1,3)])
g.edges()
#EdgeView([(1, 2), (1, 3), (2, 3)])

可以向邊中增加屬性,例如,權重,關系等:

g.add_edge(1, 2, weight=4.7, relationship=renew)

由於在圖中,邊的權重weight是非常有用和常用的屬性,因此,networkx模塊內置以一個函數,專門用於在添加邊時設置邊的權重,該函數的參數是三元組,前兩個字段是頂點的ID屬性,用於標識一個邊,第三個字段是邊的權重:

g.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)])

在增加邊時,也可以一次增加多條邊,為不同的邊設置不同的屬性:

g.add_edges_from([(1,2,{color:blue}), (2,3,{weight:8})])

2,查看邊的屬性

查看邊的屬性,就是查看邊的數據(data),查看所有邊及其屬性:

>>> g.edges(data=True)
EdgeDataView([(1, 2, {}), (1, 3, {}), (2, 3, {})])

查看特定的邊的信息有兩種方式:

>>> g[1][2]
>>> g.get_edge_data(1,2) {
weight: 0.125, relationship: renew, color: blue}

3,刪除邊

邊是兩個頂點的ID屬性構成的元組,通過 edge=(node1,node2) 來標識邊,進而從圖中找到邊:

g.remove_edge(edge)
g.remove_edges_from(edges_list)

4,更新邊的屬性

通過邊來更新邊的屬性,由兩種方式,一種是使用update函數,一種是通過屬性賦值來實現:

g[1][2][weight] = 4.7
g.edge[1][2][weight] = 4
g[1][2].update({"weight": 4.7})
g.edges[1, 2].update({"weight": 4.7})   

5,刪除邊的屬性

通過 del命令來刪除邊的屬性

del g[1][2][name]

6,檢查邊是否存在

檢查一條邊是否存在於圖中

g.has_edge(1,2)

四,圖的屬性

圖的屬性主要是指相鄰數據,節點和邊。

1,adj

ajd返回的是一個AdjacencyView視圖,該視圖是頂點的相鄰的頂點和頂點的屬性,用於顯示用於存儲與頂點相鄰的頂點的數據,這是一個只讀的字典結構,Key是頂點,Value是頂點的屬性數據。

>>> g.adj[1][2]
{weight: 0.125, relationship: renew, color: blue}
>>> g.adj[1]
AtlasView({2: {weight: 0.125, relationship: renew, color: blue}, 3: {weight: 0.75}})

2,edges

圖的邊是由邊的兩個頂點唯一確定的,邊還有一定的屬性,因此,邊是由兩個頂點和邊的屬性構成的:

>>> g.edges
EdgeView([(1, 2), (1, 3), (2, 3), (2, 4), (3, 4)])
>>> g.edges.data()
EdgeDataView([(1, 2, {weight: 0.125, relationship: renew, color: blue}), 
(1, 3, {weight: 0.75}),
(2, 3, {weight: 8}),
(2, 4, {weight: 1.2}),
(3, 4, {weight: 0.375})])

EdgeView僅僅提供邊的信息,可以通過屬性g.edges或函數g.edges()來獲得圖的邊視圖。

EdgeDataView提供圖的邊和邊的屬性,可以通過EdgeView對象來調用data()函數獲得。

3,nodes

圖的頂點是頂點和頂點的屬性構成的

>>> g.nodes
NodeView((1, 2, 3, 4))
>>> g.nodes.data()
NodeDataView({1: {name: n1 new, weight: 1}, 2: {name: n2, weight: 1.2}, 3: {}, 4: {}})

NodeView 通過屬性g.nodes或函數g.nodes()來獲得。

NodeDataView提供圖的邊和邊的屬性,可以通過NodeView對象來調用data()函數獲得。

4,degree

對於無向圖,頂點的度是指跟頂點相連的邊的數量;對於有向圖,頂點的圖分為入度和出度,朝向頂點的邊稱作入度;背向頂點的邊稱作出度。

通過g.degree 或g.degree()能夠獲得DegreeView對象,

五,圖的遍歷

圖的遍歷是指按照圖中各頂點之間的邊,從圖中的任一頂點出發,對圖中的所有頂點訪問一次且只訪問一次。圖的遍歷按照優先順序的不同,通常分為深度優先搜索和廣度優先搜索兩種方式。

1,查看頂點的相鄰頂點

查看頂點的相鄰頂點,有多種方式,例如,以下代碼都用於返回頂點1的相鄰頂點,g[n]表示圖g中,與頂點n相鄰的所有頂點:

g[n]
g.adj[n]
g.neighbors(n)

其中,g.neighbors(n)是g.adj[n]的叠代器版本。

2,查看圖的相鄰

該函數返回頂點n和相鄰的節點信息:

>>> for n, nbrs in g.adjacency():
...     print(n)
...     print(nbrs)

3,圖的遍歷

示例代碼,g是一個無向圖,n是頂點,nbrs是頂點n的相鄰頂點,是一個字典結構

for n,nbrs in g.adjacency(): 
print (n, nbrs) for nbr,attr in nbrs.items(): # nbr表示跟n連接的頂點,attr表示這兩個點連邊的屬性集合 print(nbr,attr)

六,繪制Graph

使用draw函數構造graph,使用matplotlib把圖顯示出來:

nx.draw(g)

import matplotlib.pyplot as plt
plt.show()

修改頂點和邊的顏色:

g = nx.cubical_graph()
nx.draw(g, pos=nx.spectral_layout(g), nodecolor=r, edge_color=b)
plt.show()

示例:

from matplotlib import pyplot as plt
import networkx as nx
g=nx.Graph()
g.add_nodes_from([1,2,3])
g.add_edges_from([(1,2),(1,3)])
nx.draw_networkx(g)
plt.show()

七,創建PageRank

創建PageRank時,需要傳遞一個無向圖g,使用networkx模塊中的pagerank()函數,生成的圖中,每個頂點都有特定的PageRank值。

pr=nx.pagerank(g)
page_rank_value=pr[node]

1,創建無向圖

在創建無向圖之後,向圖中增加節點和邊

g=nx.Graph() 
#向無向圖中添加節點a和節點d,且a,d之間有一條連邊
g.add_edge(a,d)   
g.add_edge(b,d)
g.add_edge(c,d)
g.add_edge(c,f)
g.add_edge(d,e)
g.add_edge(d,f)
g.add_edge(e,f)

2,創建PageRank

根據圖來創建PageRank,並查看各個頂點的PageRank值

pr=nx.pagerank(g)
for node, pageRankValue in pr.items():
    print("%s,%.4f" %(node,pageRankValue))

參考文檔:

python networkx 包繪制復雜網絡關系圖

社會網絡分析與挖掘---Python之networkx介紹

python之networkx庫小結

python復雜網絡分析庫NetworkX

Python 學習 第十六篇:networkx