NetworkX是一个用于创建、操作和研究复杂网络的结构、动态和功能的Python包。
NetworkX provides:
- 研究社会、生物和基础设施网络的结构和动态的工具;
- 适用于许多应用程序的标准编程接口和图形实现
- 快速的发展环境
- 能够轻松地处理大型非标准数据集
使用NetworkX,您可以以标准和非标准数据格式加载和存储网络,生成许多类型的随机和经典网络,分析网络结构,构建网络模型,设计新的网络算法,绘制网络等等。
install
conda install networkx 或 pip install networkx
networkx basics
在该框架中,关系图被分为四类。Graph,DiGraph,MultiDiGraph
Graph,实现无向图,规定两点间只有一条边,同时允许自己到自己的边存在
DiGraph,是Graph的子类,是有向图。
MultiGraph,允许两点之间有多边存在的无向图。
MultiDiGraph,允许两点之间有多边存在的有向图。
图创建
一切操作之前需要先创建图,在NX中,图的创建有三种方式
1.在线创建图
G = nx.Graph()
G.add_edge(1, 2) # default edge data=1
elist = [(1, 2), (2, 3), (1, 4), (4, 2)]
G.add_edges_from(elist)
elist = [('a', 'b', 5.0), ('b', 'c', 3.0), ('a', 'c', 1.0), ('c', 'd', 7.3)]
G.add_weighted_edges_from(elist)
2.读文件取图
G=nx.path_graph(4)
nx.write_adjlist(G, "test.adjlist")
G=nx.read_adjlist("test.adjlist")
文件格式为adjlist,内容如下
0 1
1 2
2 3
3
3.添加边点
例子如“在线创建图”中所示。
图中边点的增删
添加图属性、节点属性、边属性
- 图属性
G = nx.Graph(day="Friday")
G.graph
{'day': 'Friday'}
or
G.graph['day'] = "Monday"
G.graph
{'day': 'Monday'}
- 节点属性
G.add_node(1, time='5pm')
G.add_nodes_from([3], time='2pm')
G.nodes[1]
{'time': '5pm'}
G.nodes[1]['room'] = 714
G.nodes.data()
NodeDataView({1: {'time': '5pm', 'room': 714}, 3: {'time': '2pm'}})
- 边属性
G.add_edge(1, 2, weight=4.7 )
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
G[1][2]['weight'] = 4.7
G.edges[3, 4]['weight'] = 4.2
有向图
DiGraph
类为有向图。它为边提供了特殊的属性。DiGraph.out_edges()
, DiGraph.in_degree()
, DiGraph.predecessors()
, DiGraph.successors()
。在DiGraph
类中,degree是in_degree和out_degree的总和,neighbors等价于successors。
>>> DG = nx.DiGraph()
>>> DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
>>> DG.out_degree(1, weight='weight')
0.5
>>> DG.degree(1, weight='weight')
1.25
>>> list(DG.successors(1))
[2]
>>> list(DG.neighbors(1))
[2]
千万不要将有向图与无向图混为一谈,两者有很多方法是不一样的。以下方法可将有向图转为无向图。也可使用Graph.to_undirected()
>>> H = nx.Graph(G) # convert G to undirected graph
多图
NX 提供了多图类,允许两个节点之间存在多边。MultiGraph
和MultiDiGraph
允许在两个节点之间添加两条方向相同的边。但是后面最好还是要将图标准化。
>>> MG = nx.MultiGraph()
>>> MG.add_weighted_edges_from([(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)])
>>> dict(MG.degree(weight='weight'))#节点各自权重之和,
{1: 1.25, 2: 1.75, 3: 0.5}
# 将图中,两节点之间方向相同的边合并为一条,取权重最小的边为标准边,其他舍弃。
>>> GG = nx.Graph()
>>> for n, nbrs in MG.adjacency():#n,节点名称;nbrs,节点邻节点及边信息.n: 1;nbrs {2: {0: {'weight': 0.5}, 1: {'weight': 0.75}}}
... 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]
图形生成器和图形操作
除了逐点生成或逐边生成以外,也可以通过以下方式来进行图的生成。
- 应用经典图操作,例如
- subgraph(G, nbunch) - induced subgraph view of G on nodes in nbunch
- union(G1,G2) - graph union
- disjoint_union(G1,G2) - graph union assuming all nodes are different
- cartesian_product(G1,G2) - return Cartesian product graph
- compose(G1,G2) - combine graphs identifying nodes common to both
- complement(G) - graph complement
- create_empty_copy(G) - return an empty copy of the same graph class
- to_undirected(G) - return an undirected representation of G
- to_directed(G) - return a directed representation of G
- 小图调用
>>> petersen = nx.petersen_graph()
>>> tutte = nx.tutte_graph()
>>> maze = nx.sedgewick_maze_graph()
>>> tet = nx.tetrahedral_graph()
- 几个经典图生成器的使用
>>> K_5 = nx.complete_graph(5)
>>> K_3_5 = nx.complete_bipartite_graph(3, 5)
>>> barbell = nx.barbell_graph(10, 10)
>>> lollipop = nx.lollipop_graph(10, 20)
- 随机图生成器的使用
>>> 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)
- 读取常见的图格式( edge lists, adjacency lists, GML, GraphML, pickle, LEDA and others)
>>> nx.write_gml(red, "path.to.file")
>>> mygraph = nx.read_gml("path.to.file")
详细细节参阅地址 Reading and writing graphs 和Graph generators
图分析
NX支持提供各种各样的图理论函数进行图分析。
>>> G = nx.Graph()
>>> G.add_edges_from([(1, 2), (1, 3)])
>>> G.add_node("spam") # adds node "spam"
>>> list(nx.connected_components(G)) #分析连通区域
[{1, 2, 3}, {'spam'}]
>>> sorted(d for n, d in G.degree())
[0, 1, 1, 2]
>>> nx.clustering(G)
{1: 0, 2: 0, 3: 0, 'spam': 0}
有关图分析算法的详细信息及其他函数请参与 Algorithms