networkx edge 属性_NetworkX和graph-tool用法总结

总结一下图算法库NetworkX和graph-tool的基础用法。参考资料来自于官方文档。

NetworkX文档,graph-tool文档

1.NetworkX

1.1 NetworkX基础

NetworkX包括4中graph类:

Graph:无向图。两条节点之间只允许有一条边。允许节点有边指向自己。

DiGraph:有向图,Graph的子类。

MultiGraph:允许两个节点之间有多条无向边。

MultiDiGraph:MultiGraph有向图版本。

创建空的图对象:

G = nx.Graph()
G = nx.DiGraph()
G = nx.MultiGraph()
G = nx.MultiDiGraph()2.graph-tool

节点可以是任意可哈希对象,包含字符串,元祖,数字等。边等关联属性包括权重、标签等。

1.2图

图的内部数据结构基于临接表表示法,使用python字典实现。图主要由节点和边组成,节点和边都有各自的属性。NetworkX图形对象主要有两种重要属性:

Directed:节点之间是否是有向边。有向图的类用“Di”作为前缀。

Multi-Edge:节点对之间是否允许多条边连接。这种类型的数据结构和接口使用“Multi”前缀。

1.3节点和边

节点:如果只关心图的拓扑接口,可以使用字符串或数字来表示节点。如果已经定义了描述节点的数据结构,可以直接使用该结构作为节点,只要其是可哈希的(hashable)。如果其不是可哈希的,可以使用唯一标识符表示节点,将数据附值为节点属性。

边:任意数据都可以作为边都属性。如果属性是数值型且图形为加权图,那么使用“weight”关键字作为属性。一些图数据算法,比如Dijkstra的最短路径算法,默认情况下使用这个属性来获得每条边的权值。

可以使用关键字来命名属性,然后使用关键字来查询边都属性。

1.4图创建

三种创建图的方式:

1.Graph generator

2.Importing data from pre-existing (usually file) sources.

3.显示创建边和节点

下面举例说明一些图的基本操作:

显示增加节点或边

import networkx as nx
G = nx.Graph()
G.add_edge(1, 2)  # default edge data=1
G.add_edge(2, 3, weight=0.9)  # specify edge data

边的属性值可以为任意对象

import math
G.add_edge('y', 'x', function=math.cos)
G.add_node(math.cos)  # any hashable can be a node

可以同时添加多条边

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)

更多例子参考Turtorial

基本的图操作,比如交集和并集,参考Operators Module

图生成器(graph generator)subpackage中提供了诸如binomial_graph()和erdos_renyi_graph()这样的图生成器。

从GML, GraphML, edge list text files等文件导入数据到图网络中,参考reading and writing graphs

1.5 graph reporting

视图提供节点、邻居、边缘和度的基本报告。视图提供的功能包括属性的迭代,图元素的查询和属性的检索,视图引用图的数据结构,所以改变图可以直接反映到视图中。

视图相关操作:

# 返回集合对象
for e in list(G.edges): 

# 属性的检索
G.edges[u, v]['color']
for e, datadict in G.edges.items():

# 返回字典对象
G.edges.items()
G.edges.values()

# 属性迭代
for e, e_color in G.edges.data('color'):

一个边的基本图关系可以通过两种方法得到:通过查找节点的邻居或者直接查找边。NetworkX的设计者倾向于以节点为中心,将边视为节点之间的关系。可以通过查找的表示来看到这一点。比如G[u]用来查找邻接点,G.edges[u, v]用来查找边。稀疏图的大部分数据结构是邻接表。G.edges删除了无向图的重复节点。

具体参考Algorithm

1.6 算法

NetworkX提供了大量的图数据算法。其中包括最短路径、广度优先搜索(见遍历)、聚类和同构算法等。

以下是Dijkstra最短路径算法的一个例子:

>>> G = nx.Graph()
>>> e = [('a', 'b', 0.3), ('b', 'c', 0.9), ('a', 'c', 0.5), ('c', 'd', 1.2)]
>>> G.add_weighted_edges_from(e)
>>> print(nx.dijkstra_path(G, 'a', 'd'))
['a', 'c', 'd']

1.7 画图

NetworkX提供来一些绘图包接口和一些简单的布局算法。绘图包在drawing

画图举例:

>>> import matplotlib.pyplot as plt
>>> G = nx.cubical_graph()
>>> plt.subplot(121)
<matplotlib.axes._subplots.AxesSubplot object at ...>
>>> nx.draw(G)   # default spring_layout
>>> plt.subplot(122)
<matplotlib.axes._subplots.AxesSubplot object at ...>
>>> nx.draw(G, pos=nx.circular_layout(G), node_color='r', edge_color='b')

1.8 数据结构

Network使用“dictionary of dictionaries of dictionaries”作为基础图数据结构,方便用于大规模稀疏网络的查找。

G[u][v]:返回边属性。

n in G:检查节点n是否在图G中

for n in G:遍历图节点

for nbr in G[n]:遍历邻接点

# 打印图G中所有邻接信息
>>> G = nx.Graph()
>>> G.add_edge('A', 'B')
>>> G.add_edge('B', 'C')
>>> print(G.adj)
{'A': {'B': {}}, 'B': {'A': {}, 'C': {}}, 'C': {'B': {}}}

G[u][v]['width'] 等价于 G.edges[u, v]['width']. 如:

>>> G = nx.Graph()
>>> G.add_edge(1, 2, color='red', weight=0.84, size=300)
>>> print(G[1][2]['size'])
300
>>> print(G.edges[1, 2]['color'])
red

2. graph-tool

参考quick-start-using-graph_tool

graph-tool类提供了Graph类和相应的图操作方法。大多数算法的机制由C++编写,使用Boost图库来提高性能。

2.1 创建和操作图

g = Graph() # 创建图

默认为有向图,使用directed参数指定无向图。

>>> ug = Graph(directed=False)

有向图转为无向图

>>> ug = Graph()
>>> ug.set_directed(False)
>>> assert ug.is_directed() == False2.2 属性映射

使用已有的图对象创建图

>>> g1 = Graph()
>>> # ... construct g1 ...
>>> g2 = Graph(g1)                 # g1 and g2 are copies

创建节点,返回节点对象

>>> v1 = g.add_vertex()
>>> v2 = g.add_vertex()

添加边

>>> e = g.add_edge(v1, v2)

图的可视化

>>> graph_draw(g, vertex_text=g.vertex_index, vertex_font_size=18,
...            output_size=(200, 200), output="two-nodes.png")

6d1dd0e90dd301449988ea68cddc1ac7.png

图的出度和入度

>>> print(v1.out_degree())
>>> print(v2.in_degree())

边的source节点和target节点

>>> print(e.source(), e.target())

add_vertex方法添加节点,可选参数为待添加节点的数量。若添加节点的数量大于1,则返回迭代器对象。

>>> vlist = g.add_vertex(10)
>>> print(len(list(vlist)))
10

每个节点在graph-tool中,都有唯一索引,通常标识为0~N-1,N是节点数量。该索引值可以通过vertex_index[v]和int(v)获取。

>>> v = g.add_vertex()
>>> print(g.vertex_index[v])
12
>>> print(int(v))
12

使用remove_vertex和remove_edge方法删除节点和边。

>>> g.remove_edge(e)                               # e no longer exists
>>> g.remove_vertex(v2)                # the second vertex is also gone

vertex方法通过节点索引来获取节点对象

>>> v = g.vertex(8)

edge方法通过给定或source节点和target节点都索引来获取边。

>>> g.add_edge(g.vertex(2), g.vertex(3))
<...>
>>> e = g.edge(2, 3)

同时,获取节点或者边可以通过迭代方法,参考Iterating over vertices and edges

与节点类似,边也有唯一索引。edge_index获取边都索引。如果删除了某条边,其索引为空,其他边都索引不变。

>>> e = g.add_edge(g.vertex(0), g.vertex(1))
>>> print(g.edge_index[e])
1

2.1.1 迭代顶点和边

迭代所有的顶点或边

for v in g.vertices():
    print(v)
for e in g.edges():
    print(e)

迭代顶点的邻接点。out_edges, out_neighbors, in_edges, in_neighbors方法

for v in g.vertices():
   for e in v.out_edges():
       print(e)
   for w in v.out_neighbors():
       print(w)

   # the edge and neighbors order always match
   for e, w in zip(v.out_edges(), v.out_neighbors()):
       assert e.target() == w

快速迭代节点和边

graph-tool提供了基于数组的接口,比如get_vertices(), get_edges(), get_out_edges(), get_in_edges(), get_all_edges(), get_out_neighbors(), get_in_neighbors(), get_all_neighbors(), get_out_degrees(), get_in_degrees() and get_total_degrees()

这些方法返回numpy.ndarray的实例而不是迭代器。

2.2 属性映射

属性映射是将附加信息关联到顶点、边或图本身的一种方式。有三种类型的属性映射:顶点、边和图。它们由类VertexPropertyMap、EdgePropertyMap和GraphPropertyMap处理。每个创建的属性映射都有一个关联的值类型,必须从预定义的集合中选择:

创建新的属性映射的方法:

new_vertex_property: 别名new_vp

new_edge_property: 别名new_ep

new_graph_property: 别名new_gp

属性映射,可以通过顶点、边或图进行赋值。

from numpy.random import randint

g = Graph()
g.add_vertex(100)

# insert some random links
for s,t in zip(randint(0, 100, 100), randint(0, 100, 100)):
    g.add_edge(g.vertex(s), g.vertex(t))

vprop_double = g.new_vertex_property("double")            # Double-precision floating point
v = g.vertex(10)
vprop_double[v] = 3.1416

vprop_vint = g.new_vertex_property("vector<int>")         # Vector of ints
v = g.vertex(40)
vprop_vint[v] = [1, 3, 42, 54]

eprop_dict = g.new_edge_property("object")                # Arbitrary Python object.
e = g.edges().next()
eprop_dict[e] = {"foo": "bar", "gnu": 42}                 # In this case, a dict.

gprop_bool = g.new_graph_property("bool")                 # Boolean
gprop_bool[g] = True

可以通过numpy.ndarray赋值

from numpy.random import random

# this assigns random values to the vertex properties
vprop_double.get_array()[:] = random(g.num_vertices())

# or more conveniently (this is equivalent to the above)
vprop_double.a = random(g.num_vertices())

通过edge_properties, vertex_properties, graph_properties,将属性映射内化到图中。

>>> eprop = g.new_edge_property("string")
>>> g.edge_properties["some name"] = eprop
>>> g.list_properties()
some name      (edge)    (type: string)

内部图属性映射略有不同。返回的不是属性映射,而是值本身。

>>> gprop = g.new_graph_property("int")
>>> g.graph_properties["foo"] = gprop   # this sets the actual property map
>>> g.graph_properties["foo"] = 42      # this sets its value
>>> print(g.graph_properties["foo"])
42
>>> del g.graph_properties["foo"]       # the property map entry is deleted from the dictionary

内部属性映射也可以通过属性访问(下面代码中的foo可能是属性映射名称)

>>> vprop = g.new_vertex_property("double")
>>> g.vp.foo = vprop                        # equivalent to g.vertex_properties["foo"] = vprop
>>> v = g.vertex(0)
>>> g.vp.foo[v] = 3.14
>>> print(g.vp.foo[v])
3.14

2.3 图IO

图的保存和加载。

g = Graph()
#  ... fill the graph ...
g.save("my_graph.xml.gz")
g2 = load_graph("my_graph.xml.gz")
# g and g2 should be copies of each other

2.4 例子:building a price network

略。

2.5 图过滤

略。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值