NetworkX使用笔记:读入外部文件并转换成各种格式

复杂网络分析工具众多,有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')

发表评论

电子邮件地址不会被公开。 必填项已用*标注

4 thoughts on “NetworkX使用笔记:读入外部文件并转换成各种格式