轉:http://baiyejianxin.iteye.com/blog/1764048
創建簡單的空圖形(沒有邊和點)
import networkx as nx
g = nx.Graph();
h = nx.Graph( g); #可以在構建Graph對象時指定值來構造一個新的Graph對象
f = nx.Graph( [ (1,2),(2,3),(1,3)]); #可以在構建Graph對象時指定node關系的數組來構建Graph對象
根據定義,一個Graph就是一個所有nodes的集合。在NetworkX中,nodes能夠代表任何對象,例如一個文本,一個圖片,一個xml對象或者另外一個Graph,一個自定義的對象等等。
由於NetworkX提供了多種Graph對象生成方法,並且體痛了讀寫方法來讀寫多種格式,所以Graph對象能夠使用多種方式創建。
----------------------
Nodes
graph對象能夠添加node(節點)
g.add_node(1); #添加一個節點
g.add_nodes_from( [2,3]) #添加一個節點列表
h = nx.path_graph(10)
g.add_nodes_from( h) #添加一個能夠迭代的集合(例如:list, set, graph, file等等),這樣g中包含了h中的元素
g.add_node( h) #這是將h作為一個node添加到g中
g.add_nodes_from( 'span'); #將span拆分為一個字符數組,然后添加node
Note: 最后,h是一個graph對象,將h最為g的node,是一個很靈活的特性。這樣節點可以是graph中的graph,files中的graphs,method中的graph等等。值得思考的是,如果結構化你的應用使得那些node都是有用的實體。如果你願意,你還可以是g對應一個唯一的表示,每個node對應一個被表示的key。如果node對應的是對象中的內容,那么當內容變化是,不應該修改對象,應該修改node對應的內容(有點繞)。
-----------------------
Edges
graph對象中還能夠添加edges(邊);
g.add_edge(1,2) # 添加一個1和2之間的edge
e=(2,3) #定義個關系
g.add_edge( *e) #添加關系對象
g.add_edges_from([(1,2),(2,3)]) #添加一個edge數組
g.add_edges_from( h.edges()); #h.edges()返回的h的包含所有edge的數組
#拆除graph對象中的node和edge可以使用如下方法
g.remove_node()
g.remove_nodes_from()
g.remove_edge()
g.remove_edges_from()
#刪除所有的node和edge
g.clear();
#如果重復添加相同的node和edge,NetworkX將會將會忽略那些重復的內容。
g.add_nodes_from("span");
g.add_node( "s");
#獲取一個Graph對象中node和edge的數量
g.number_of_nodes();
g.number_of_edges();
#獲取一個Graph對象中的node數組或者edge數組
g.nodes();
g.edges();
g.neighbors(1); #獲取與node為1相鄰的node是節點
g.remove_edge( 1,2); #刪除node1和node2之間的edge,自此node1和node2不再為相鄰的node
------------------------------
如何使用nodes和edges?
獲取你已經注意到了node和edge並不是Graph的對象。這就能夠使你更加靈活的使用node和edge,如果在python中使用string和number。node可以為任何hashable對象(除了Node),edge還可以和其他Graph對象中的node建立關聯。例如:
g.add_node( n1, n2, Graph=x);
例如,n1,n2可以代表生物蛋白質資料庫中兩種蛋白質對象,x可以是代表一個觀察實驗出版物中的xml片段記錄。
如果熟悉他們,那么他們會非常有用。如果濫用也會帶來意想不到的結果。如有疑問可以通過convert_node_labels_to_integers()方法來獲得更多的有整數組成的傳統圖形。
-------------------------
除了使用上面提到的方法外,可以使用索引下標來訪問edge
>>>g[1]
{2,{}}
>>>g[1][1]
{}
Note:不要修改返回到額字典結構,它是graph固有的一部分,直接修改會導致不一致的狀態
同樣通過下標可以設置edge的屬性
g.add_edge( 1, 3)
g[1][1][ "color"] = "blue"
通過迭代快速查找所有的edge
>>> FG=nx.Graph() >>> FG.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)]) >>> for n,nbrs in FG.adjacency_iter(): ... for nbr,eattr in nbrs.items(): ... data=eattr['weight'] ... if data<0.5: print('(%d, %d, %.3f)' % (n,nbr,data)) (1, 2, 0.125) (2, 1, 0.125) (3, 4, 0.375) (4, 3, 0.375)
--------------------
添加graph,node,edge的屬性
像color,label,weight或者其他Python對象的屬性都可以被設置為graph,node,edge的屬性。
每個graph,node,edge都能夠包含key/value這樣的字典數據。默認情況下是沒有這些屬性的。可以通過add_node(),add_edge(),或者直接修改來添加和修改屬性。
Graph 屬性
g = nx.Graph( day="friday");
g.graph
打印:{“day”:“friday”}
g.graph["day"]="Monday";
g.graph
打印:{"day":"Monday"}
Node屬性
通過add_node(),add_nodes_from或者g.node來添加屬性
g.add_node( 1, time="5pm");
g.add_nodes_from([3], time="2pm");
g.node[ 1]
打印:{"time":"5pm"}
g.node[1]["room"]=714;
g.nodes(data=True);
打印:[(1,{"room":714, "time":"5pm"}),(3,{"time":"2pm"})]
Note:向node添加屬性並不會想graph添加屬性,
Edge屬性
通過add_edge(), add_edges_from()或者g.edge來添加屬性
g.add_edge(1,2,wegiht=4.7)
g.add_edges_from( [ (2,3),(3,4) ], color="red")
g.add_edges_from( [(1,2,{"color":"blue"}),(4,5,{"weight":8})])
g[1][2]["width"]=4.7
g.edge[1][2]["weight"]=4
-----------------------------
Directed graphs(有向圖)
DiGraph類針對有向edge提供了另外的方法,例如:out_edges(), in_degree(),predecessors(),successors()等。為了是算法能夠正常運行,有向版本的neighbors()和degree()對於seccessor()方法是相同的。in_degree()和out_degree()都是獨自的。
ig = nx.DiGraph()
ig.add_wieghted_edges_from( [(1,2,0.5),(2,3,0.7)])
ig.out_degree( 1,weight="weight");
打印:0.5
ig.degree( 1, weight="weight");
打印:1.25
ig.seccessors(1)
打印:[2]
ig.neighbors(1)
打印:[2]
一些算法只對有向grapsh起作用,其他算法沒有明確定義。同時使用有向graph和無向graph是非常危險的事情。如果想將有向graph轉換為無向graph可以使用
Graph.to_undirected()
或者
h = nx.Graph( g)
-------------------
Multigraphs
NetworkX提供了類來實現一對node之間存在多個edge的實現類:MultiGraph和MultiDiGraph,他們都允許使用的edge數據添加多個的edge。對於某些應這個特性非常有用,但是很多算法在這種graph中並沒有明確定義。
>>> MG=nx.MultiGraph() >>> MG.add_weighted_edges_from([(1,2,.5), (1,2,.75), (2,3,.5)]) >>> MG.degree(weight='weight') {1: 1.25, 2: 1.75, 3: 0.5} >>> GG=nx.Graph() >>> for n,nbrs in MG.adjacency_iter(): ... for nbr,edict in nbrs.items(): ... minvalue=min([d['weight'] for d in edict.values()]) ... GG.add_edge(n,nbr, weight = minvalue) ... >>> nx.shortest_path(GG,1,3) [1, 2, 3]
---------------------
Graph generators and graph operations(圖形生成和操作)
為了構建node-by-node或者edge-by-edge的graph,還可以使用以下方式。
subgraph( G, nbunch)
union( g1,g2) #合並praph
disjoint_union( g1, g2) #假設所有node都不相同合並praph
cartesian_product( g1, g2) #返回笛卡爾產品praph
compose( g1, g2) #合並公共的node
complement( g1) #praph的補集
create_empty_copy( g) #返回某個praph對象的空的拷貝對象
convert_to_undirected( g) #返回一個無向praph
convert_to_directed( g) #返回一個有向的praph
使用小圖的調用
petersen = nx.petersen_parph();
tutte = nx.tutte_praph()
maze = nx.sedgewick_maze_praph()
tet = nx.tetrahedral_praph()
使用典型praph的構造生成器
k_4 = nx.complete_graph(4);
k_3_5 = nx.complete_bipartite_graph(3,5)
barbell = nx.barbell_graph( 10, 10)
lollipop = nx.lollipop_graph( 10,20);
使用隨機graph生成器
>>> er=nx.erdos_renyi_graph(100,0.15) >>> ws=nx.watts_strogatz_graph(30,3,0.1) >>> ba=nx.barabasi_albert_graph(100,5) >>> red=nx.random_lobster(100,0.9,0.9)
從存儲praph的文件中讀取格式數據然后生成praph。
>>> nx.write_gml(red,"path.to.file") >>> mygraph=nx.read_gml("path.to.file")
--------------
Analyzing graphs(分析圖)
結構話的praph能夠使用提供的方法來進行分析:
g = nx.Graph()
g.add_edges_from( [(1,2),(1,3)])
g.add_node( "spam")
nx.connected_components( g) #將node有關聯的顯示一個數組中。返回的為一個數組
打印: [ [1,2,3], [ "spam"]]
sorted( nx.degree( g).values())
打印: [ 0, 1, 1, 2]
nx.clustering( g) #聚合
打印: { 1 : 0.0, 2:0.0 , 3: 0.0 . "spam":0.0}
nx.degree( g) #顯示等級
打印:{1:2, 2:1,3:1,"spam":0}
對於特殊的node,可以將一個單獨的node或者node集合作為參數。如果傳入一個獨立的node,那么返回一個獨立的值,如果傳入一個node集合,這個方法將返回一個字典類型的數據
nx.degree(g,1) #返回第一個node的值
2
g.degree( 1) #返回第一個node的值
2
g.degree( 1, 2) #返回從第一個node開始,前兩個node的值
{1:2, 2:1}
sorted( g.degree( [ 1, 2]).values()) #返回1和2並排序輸出結果
[1,2]
sorted( g.degree().values()) #返回g中node的權重,並排序輸出結果
想要了解更加詳細的算法只是,參考:
算法
---------------------
Drawing Praphs(繪制圖形)
NetworkX並不是首選的圖形繪制包,但是它包含了基本的圖形繪制工具開源包Matplotlib。如果需要的話可以引入network.drawing包。(更詳細的文檔參考:
Drawing)
注意: NetworkX中的繪圖包不和Python3兼容
首先引入 Matplotlib的plot接口
import matplotlib.pyplot as plt
如果成功引入 networkx.drawing那么可以使用下面的方法繪制graph對象
nx.draw( g)
nx.draw_random( g)
nx.draw_circular( g)
nx.draw_spectral( g)
將繪制的內容保存的一個文件中使用下面的方法
nx.draw( g)
plt.savefig( "path.png")
數據分析學習筆記(四)-使用NetworkX進行數據分析的實例
