zoukankan      html  css  js  c++  java
  • networkx详细教程

    写在前面:城市计算研究中经常涉及到图论的相关知识,而且常常面对某些术语时,根本不知道在说什么.最近接触了NetworkX这个graph处理工具,发现这个工具已经解决绝大部分的图论问题(也许只是我自己认为的,没有证据证明),所以把这个工具的使用学习下,顺便学习图论的相关知识.

    创建一个图

    import networkx as nx
    G = nx.Graph()

    节点

    一次添加一个节点
    G.add_node(1)
    
    添加一个节点列表
    G.add_nodes_from([2, 3])

    可以通过一次添加一条边来增长
    G.add_edge(1, 2)
    e = (2, 3)
    G.add_edge(*e)  # unpack edge tuple*
    
    也可以通过添加边列表
    G.add_edges_from([(1, 2), (1, 3)])

    删除图中所有节点和边

    G.clear()

    我们添加新的节点/边,并且NetworkX会自动的忽略任何已经存在的节点。

    G.add_edges_from([(1, 2), (1, 3)])
    G.add_node(1)
    G.add_edge(1, 2)
    G.add_node("spam")        # adds node "spam"
    G.add_nodes_from("spam")  # adds 4 nodes: 's', 'p', 'a', 'm'
    G.add_edge(3, 'm')

    在这个阶段,图形G由8个节点和3个边组成,如下所示:

    >>> G.number_of_nodes()
    8
    >>> G.number_of_edges()
    3

    我们可以检查节点和边。四个基本图形属性:G.nodesG.edgesG.adjG.degree。这些是节点,边,邻居(邻接点)和图中节点的程度集的视图。

    >>> list(G.nodes)
    ['a', 1, 2, 3, 'spam', 'm', 'p', 's']
    >>> list(G.edges)
    [(1, 2), (1, 3), (3, 'm')]
    >>> list(G.adj[1])  # or list(G.neighbors(1))
    [2, 3]
    >>> G.degree[1]  # the number of edges incident to 1
    2

    可以以类似于添加的方式从图中移除节点和边。使用方法 Graph.remove_node()Graph.remove_nodes_from(), Graph.remove_edge() 和 Graph.remove_edges_from(),如

    >>> G.remove_node(2)
    >>> G.remove_nodes_from("spam")
    >>> list(G.nodes)
    [1, 3, 'spam']
    >>> G.remove_edge(1, 3)

    通过实例化其中一个图形类来创建图形结构时,可以使用多种格式指定数据

    >>> G.add_edge(1, 2)
    >>> H = nx.DiGraph(G)   # create a DiGraph using the connections from G
    >>> list(H.edges())
    [(1, 2), (2, 1)]
    >>> edgelist = [(0, 1), (1, 2), (2, 3)]
    >>> H = nx.Graph(edgelist)

    访问边和节点邻居

    除了视图之外Graph.edges()Graph.adj()还可以使用下标符号来访问边和邻居。

    >>> G[1]  # same as G.adj[1]
    AtlasView({2: {}})
    >>> G[1][2]
    {}
    >>> G.edges[1, 2]
    {}

    如果边已经存在,可以使用下标符号来获取/设置边的属性。

    >>> G.add_edge(1, 3)
    >>> G[1][3]['color'] = "blue"
    >>> G.edges[1, 2]['color'] = "red"

    所有(节点,邻接节点)的快速查询都是使用 G.adjacency()G.adj.items()完成的。请注意,对于无向图,邻接迭代会将每个边看两次。

    >>> 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.adj.items():
    ...    for nbr, eattr in nbrs.items():
    ...        wt = eattr['weight']
    ...        if wt < 0.5: print('(%d, %d, %.3f)' % (n, nbr, wt))
    (1, 2, 0.125)
    (2, 1, 0.125)
    (3, 4, 0.375)
    (4, 3, 0.375)

    通过边属性可以方便地访问所有的边。

    >>> for (u, v, wt) in FG.edges.data('weight'):
    ...     if wt < 0.5: print('(%d, %d, %.3f)' % (u, v, wt))
    (1, 2, 0.125)
    (3, 4, 0.375)

    将属性添加到图形,节点和边

    属性(如权重,标签,颜色或任何您喜欢的Python对象)可以附加到图形,节点或边上。

    每个图形,节点和边都可以在关联的属性字典中保存键/值属性对(键必须是可散列的)。默认情况下,这些都是空的,但属性可以使用添加或更改add_edgeadd_node或命名的属性字典的直接操作G.graphG.nodes和 G.edges一个图G。

    图形属性

    创建新图形时分配图形属性

    >>> G = nx.Graph(day="Friday")
    >>> G.graph
    {'day': 'Friday'}

    或者也可以修改属性

    >>> G.graph['day'] = "Monday"
    >>> G.graph
    {'day': 'Monday'}

    节点属性

    添加节点属性使用add_node()add_nodes_from()G.nodes

    >>> 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: {'room': 714, 'time': '5pm'}, 3: {'time': '2pm'}})

    边属性

    添加/更改边使用的属性add_edge()add_edges_from()或标符号。

    >>> 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类提供特定于有向边的附加属性,例如DiGraph.out_edges()DiGraph.in_degree()DiGraph.predecessors()DiGraph.successors()等。为了使算法能够轻松地处理这两个类, neighbor()的功能等同于successors(),而degree会报告in_degreeout_degree的总和,即使有时可能会感觉不一致

    dg = nx.DiGraph()
    nodes1 = [
        ('Variable', {'name': 'avariable', 'table': 'tablename'}),
        ('Select', {'conditions': {'pro_code': 44}}),
        ('GroupBy', {'varname': 'gender'}),
        ('Mean', {}),
        ('Which1', {'level': 1}),
        ('Decimal1', {'place': 1}),
    ]
    
    nodes2 = [
        ('Which1', {'level': 2}),
        ('Decimal2', {'place': 1}),
    ]
    
    nodes3 = [
        ('Add', {})
    ]
    
    dg.add_nodes_from(nodes1)
    dg.add_nodes_from(nodes2)
    dg.add_nodes_from(nodes3)
    dg.add_edges_from([
        ('Variable', 'Select'),
        ('Select', 'GroupBy'),
        ('GroupBy', 'Mean'),
        ('Mean', 'Which1'),
        ('Mean', 'Which2'),
        ('Which1', 'Decimal1'),
        ('Which2', 'Decimal2'),
        ('Decimal1', 'Add'),
        ('Decimal2', 'Add'),
    ])
    
    nx.draw(dg, with_labels=True)

  • 相关阅读:
    如何在SpringMVC项目中部署WebService服务并打包生成客户端
    Spring MVC前后端数据交互总结
    JAVA总结---序列化的三种方式
    jackson中的@JsonBackReference和@JsonManagedReference,以及@JsonIgnore
    Jackson-deserialization fails on circular dependencies(JackSon无限递归问题)
    @JsonIgnore @JsonIdentityInfo 处理Hibernate 循环引用的问题
    hibernate中因双向依赖而造成的json怪相--springmvc项目
    jackson java转json hibernate懒加载造成的无限递归问题
    C/C++使用心得:enum与int的相互转换
    浅析长子继承制对英国社会的影响
  • 原文地址:https://www.cnblogs.com/USTC-ZCC/p/11929088.html
Copyright © 2011-2022 走看看