networkx是Python的一個包,用於構建和操做複雜的圖結構,提供分析圖的算法。圖是由頂點、邊和可選的屬性構成的數據結構,頂點表示數據,邊是由兩個頂點惟一肯定的,表示兩個頂點之間的關係。頂點和邊也能夠擁有更多的屬性,以存儲更多的信息。html
對於networkx建立的無向圖,容許一條邊的兩個頂點是相同的,即容許出現自循環,可是不容許兩個頂點之間存在多條邊,即出現平行邊。邊和頂點均可以有自定義的屬性,屬性稱做邊和頂點的數據,每個屬性都是一個Key:Value對。node
在建立圖以前,須要導入networkx模塊,一般設置別名爲nx;若是建立的圖中,頂點之間的邊沒有方向,那麼該圖稱做無向圖。在建立圖時,能夠經過help(g)來得到圖的幫助文檔。python
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屬性是頂點的其餘屬性構成的一個字典。spa
>>> g._node {1: {'name': 'n1', 'weight': 1}, 2: {'name': 'n2', 'weight': 1.2}, 3: {}, 4: {}}
>>>g.nodes(data=True)
能夠經過頂點的ID屬性來查看頂點的其餘屬性:.net
>>> 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對象,
圖的遍歷是指按照圖中各頂點之間的邊,從圖中的任一頂點出發,對圖中的全部頂點訪問一次且只訪問一次。圖的遍歷按照優先順序的不一樣,一般分爲深度優先搜索(DFS)和廣度優先搜索(BFS)兩種方式。
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,圖的遍歷
深度優先遍歷的算法:
深度優先遍歷算法的思想是:從一個頂點出發,一條路走到底;若是此路走不通,就返回上一個頂點,繼續走其餘路。
廣度優先遍歷的算法:
廣度優先遍歷算法的思想是:以v爲起點,按照路徑的長度,由近至遠,依次訪問和v有路徑相通且路徑長度爲1,2...,n的頂點。
在進行圖遍歷時,須要訪問頂點的相鄰頂點,這須要用到adjacency()函數,例如,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)
使用networkx模塊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(簡稱PR)值,是訪問頂點的機率,能夠經過networkx.pagerank()函數來計算,該函數根據頂點的入邊和邊的權重來計算頂點的PR值,也就是說,PR值跟頂點的入邊有關,跟入邊的weight(權重)屬性有關:
pagerank(g, alpha=0.85, personalization=None, max_iter=100, tol=1e-06, nstart=None, weight='weight', dangling=None)
經常使用參數註釋:
1,舉個例子
例如,建立一個有向圖,由三個頂點(A、B和C),兩條邊(A指向B,A指向C),邊的權重都是0.5
g=nx.DiGraph() g.add_weighted_edges_from([('A','B',0.5),('A','C',0.5)]) print( nx.pagerank(g)) #{'A': 0.259740259292235, 'C': 0.3701298703538825, 'B': 0.3701298703538825}
修改邊的權重,並查看頂點的PR值:
g['A']['C']['weight']=1 print( nx.pagerank(g)) # {'A': 0.259740259292235, 'C': 0.40692640737443164, 'B': 0.3333333333333333}
2,查看各個頂點的PR值
根據圖來建立PageRank,並查看各個頂點的PageRank值
pr=nx.pagerank(g) #page_rank_value=pr[node] for node, pageRankValue in pr.items(): print("%s,%.4f" %(node,pageRankValue))
參考文檔: