Graph NetworkX 库

Graph Model

Github : site

1. Definition

Nodes: \(N\)

Arcs (or branches, or edges) \(A\)

  • Directed arcs (or oriented arcs)

  • Undirected arcs (or unoriented arcs)

Networks (or Graph) \(G = (N,A)\)

  • tree

  • spanning tree

Path

  • cycle (or loop)

2. NetworkX instruction

2.1. Construction

2.1.1 Graph

  • Construction a network
G = nx.Graph()     # 无向图
G = nx.DiGraph()   # 有向图

Multigraph:允许两个 node 之间存在多条边

G = nx.MultiGraph()   # 无向图
G = nx.MultiDiGraph() # 有向图
G.graph["Name"] = "Bar"    # Add graph level attribute
G.clear()  # 删除所有 node 和 edge

2.1.2 Node

  • add node
G.add_node(1)        # 1 is node id
G.add_node('spam')   # adds node "spam"
G.add_node(0, feature=5, label=0)   # Add one node with node level attributes

G.add_nodes_from([1, 2, 3, 4, 5]) # add 5 nodes
G.add_nodes_from('spam')          # adds 4 nodes: 's', 'p', 'a', 'm'
G.add_nodes_from([                # Add multiple nodes with attributes
  (1, {"feature": 1, "label": 1}),
  (2, {"feature": 2, "label": 2})]) # (node, attrdict)
  • remove node
G.remove_node(1)
G.remove_nodes_from([1, 2, 3, 4, 5])

2.1.3 Edge

  • add edge

如果所添加 Edge 的 Node 不存在,则会自动创建相应的 Node

G.add_edge(1, 2)                # add edge from Node 1 to Node 2
G.add_edge(1, 2, weight = 0.5)  # add edge with attribute

G.add_edges_from([(1, 2), (1, 3), (2, 3)])
G.add_edges_from([           # Add multiple edges with edge attribute
  (1, 2, {"weight": 0.3}),
  (2, 0, {"weight": 0.1})])

G.add_weighted_edges_from([(1, 2, 1.5)])
G.add_weighted_edges_from([(1, 2, 1.5), (1, 3, 0.5), (2, 3, 2.5)])
  • remove edge
G.remove_edge(1, 2)
G.remove_edges_from([(1, 2), (1, 3), (2, 3)])
G.clear_edges()   # 删除所有 edges,但是保留 node

2.1.4 Construct a network

(1) From Adjacency matrix

nx.from_numpy_array(A, parallel_edges=False, create_using=None)

nx.from_numpy_matrix(A, parallel_edges=False, create_using=None)

nx.from_pandas_adjacency(df, create_using=None)

  • 从 adjacency matrix \(A\) 构建一个 network:

    • 非 0 (包括负数和正数)的矩阵元素,即 \(A_{ij} \ne 0\),会被创建为 edge;

    • 如果对角线元素不为 0 ,即 \(A_{ii} \ne 0\),则会创建自连接的 edge

    • 非 0 的 \(A_{ij}\) 将会被解析为 edge 的 weight 属性。node 的 id 为 0, 1, 2, ...

    • edge 两端的 nodes:起点为行索引(0,1,..),终点为列索引

  • create_using = nx.Graph(),即创建无向图,连接矩阵 \(A\) 首先会通过(左)下三角进行对称(A1 = np.tril(A) + np.tril(A).T - np.diag(A.diagonal()))。

  • parallel_edges=True, create_using = nx.Graph(),即创建多边无向图,要求矩阵 \(A\) 的元素必须为 正数

G = nx.from_numpy_array(A, create_using=nx.Graph())
G = nx.from_numpy_array(A, create_using=nx.DiGraph())
G = nx.from_numpy_array(A, parallel_edges=True, create_using=nx.MultiGraph())
  • 代码实例: Adjacency matrix to graph
点击查看代码
def MatrixToGraph(D, directed=False, nodes_li=None):
    '''
    distance matrix to network object

    params:
    -------
    D : 2-d numpy.ndarray, shape of (n, n)
        distance matrix
    directed :
        False : nx.Graph() undirected graph
        True : nx.DiGraph() directed graph
    nodes_li : list, len(nodes_li) = n
        node lable
    '''

    # D distance matrix
    if directed:
    	G = nx.DiGraph()
    else:
        G = nx.Graph()
    
    n = D.shape[0]
    if nodes_li is None: nodes_li = list(range(n))
    G.add_nodes_from(nodes_li)

    for i in range(n):
        for j in range(n):
            if j == i: continue
            if not np.isinf(D[i,j]): # np.isnan(D[i,j])
                G.add_weighted_edges_from([(nodes_li[i], nodes_li[j], D[i,j])])
    return G

(2) From Edge list

nx.from_edgelist(edgelist, create_using=None)

nx.from_pandas_edgelist(df, source='source', target='target', edge_attr=None, create_using=None, edge_key=None)

2.2. Accessing element

2.2.1 Accessing node

  • accessing node
# all nodes
G.nodes    # 包含所有 node 的对象,可通过 for 遍历
G.nodes()
G.nodes(data=True)  # 包含 node 的属性

G.nodes[1]  # return the attribute of node 1, 1 is the node id
  • accessing neighbor nodes
# return an iterator
G.neighbors(1)    # for undirected graph, the neighbors of node 1
                  # for directed graph, equal to the union set between G.predecessors(1) and G.successors(1)
G.adj    # return : 类 dict; 包含所有 node 的邻接 nodes
  • predecessors and successors: only for directed graph
# return an iterator
G.predecessors(1) # only used for directed graph, the predecessors of node 1
G.successors(1)   # only used for directed graph, the successors of node 2

2.2.1 Accessing edge

  • accessing edge
# all edges
G.edges
G.edges()
G.edges(data=True)

G[0] # return : dict; the edges start from node 0
G.edges()[(0, 1)]  # Get attributes of the edge (0, 1)
G[0][1]          # return : dict; the attributes of the edge (0, 1)
G[0][1]['weight'] 

2.3. Properties of Graph

图类型

G.is_directed()      # 返回 bool
# 注意,没有 G.is_undirected()

图元素

G.number_of_nodes()  # 返回 node 数量
G.order()            # 返回 node 数量
G.__len__()          # 返回 node 数量
G.number_of_edges()  # 返回 edge 数量

2.4. Display

  • 代码实例: 展示一个图
点击查看代码
def DisplayGraph(G):
    '''
    # parameters:https://networkx.org/documentation/stable/_modules/networkx/drawing/nx_pylab.html#draw_networkx
    '''

    plt.figure()
    # graph layout 
    pos = nx.shell_layout(G)

    # draw graph
    nx.draw(G, with_labels=True, pos=pos, 
            node_size=1000, node_color="#ffff8f", width=0.8, font_size=14)
    
    # draw edge weights
    weights = [G[i[0]][i[1]]['weight'] for i in list(G.edges)]
    edge_labels = {v:weights[i] for i,v in enumerate(list(G.edges))}
    nx.draw_networkx_edge_labels(G, edge_labels=edge_labels, pos=pos)

    return None

3. Tools

Gephi: Networks display

Networkx : Python Package

scipy.sparse.csgraph:module of SciPy, Python Package

Reference

[1] Networkx Tutorial

posted @ 2022-03-30 08:52  veager  阅读(254)  评论(0)    收藏  举报