复杂网络分析工具众多,有NetworkX,igraph, Pajek, Gephi,这些工具支持的文件格式不尽相同。利用NetworkX库可以很方便地在不同格式间进行转换。本文介绍如何利用NetworkX读入外部文件,并转换成其他格式,最后介绍如何将自动生成的图固定保存下来。
1. 读入外部文件
1.1 现成方法的不足
NetworkX提供很多现成的方法将存储在外部文件的图读入,详情参考这里《Reading and writing graphs》。但要使用这些方法,必须得遵循其指定的格式,如使用read_adjlist(Adjacency List),其格式及使用方法如下:
#Adjacency List格式如下: a b c #source target target ... 类似于邻接多重表存储 d e #使用方法如下: #read_adjlist(path, comments='#', delimiter=None, create_using=None, nodetype=None, encoding='utf-8') G=nx.read_adjlist("test.adjlist", nodetype=int) #默认是无向图 G=nx.read_adjlist("test.adjlist", create_using=nx.DiGraph()) #有向图
使用现成的方法,需要先转换成要求的格式,需要不少编码工作。除此之外,现成的文件格式也许不能满足需求,如上例,尽管可以表示有向无向图,但不能表示有权图,也不能存储节点或边的属性。我
我个人的经验的是,自己利用Python读取外部文件,手动创建图。
1.2 读入外部文件
我保存图的文件格式如下(处理一些数据集得到的):
#n1 n2 weight1 weight2
0 28 61.9302 274209
0 77 500.083 33958
读入外部文件并创建图,Python源码如下:
### read edge list to networkx ### # the format of each line: (src dst whole_duration/total_duration total_duration) def createGraph(filename, w_index) : G = nx.Graph() for line in open(filename) : strlist = line.split() n1 = int(strlist[0]) n2 = int(strlist[1]) weight = float(strlist[w_index]) G.add_weighted_edges_from([(n1, n2, weight)]) #G.add_edges_from([(n1, n2)]) return G
1.3 输出图形
将上述的图画出来,为了直观,标出节点的id,源代码如下:
import matplotlib.pyplot as plt #assign node ID as nodes' label. G.nodes return a list of nodes, convert list to dict labels = dict((i,i) for i in G.nodes()) nx.draw_networkx_labels(G, pos=nx.spring_layout(G), labels) plt.savefig(filename) plt.show
2. 转换成其他格式
读入文件,创建图,这样就可以保存为NetworkX支持的任意格式,以保存为.net格式(Gephi, Pajek都支持)为例,源代码如下:
#write_pajek(G, path, encoding='UTF-8')
nx.write_pajek(G, file_pajek)
其他格式可以参考
Edge List
GEXF
GML
Pickle
GraphML
JSON
LEDA
YAML
SparseGraph6
Pajek
GIS Shapefile
就个人经历而言,以上有些格式写入然后读出,并不完全相同,如位置信息pos。详情见3。
3. 固定自动生成图形
先简单说下个人经历:之前导师要求我将所有衡量节点中心度(node centrality)的指标都找出来,并用例子说明是如何求得的。很自然,我就想所有指标都用同一个例子,这就需要用NetworkX生成图之后,保存起来,下次要用的时候,再从文件读取。
我当时试了很多种格式,有很多格式再读出来时,节点的位置变了,包括以下:
nx.write_gml(G, "florentine_families_graph.gml") nx.write_pajek(G, "florentine_families_graph.net") nx.write_adjlist(G, "florentine_families_graph.adjlist") G = nx.read_gml("florentine_families_graph.gml", relabel=True) G = nx.read_pajek("florentine_families_graph.net")
最后,用了gpickle格式,输出的图是一样的,相关源码如下:
#自动生成一个图 G = nx.florentine_families_graph() pos = nx.spring_layout(G) nx.set_node_attributes(G, 'pos', pos) nx.write_gpickle(G, "florentine_families_graph.gpickle") #从文件读取,创建图 G = nx.read_gpickle("florentine_families_graph.gpickle") pos = nx.get_node_attributes(G, 'pos')赞赏
微信赞赏
支付宝赞赏
你的数据为什么会有两个权重? weight1 weight2?
w_index 也就是选哪个权重的意思吧?
请问:w_index是什么?
w_index
在我代码中是指权重(weight)的下标。Pingback: NetworkX使用笔记:基本操作 | Spark and Shine