2014-09-11 135 views
1

我有一些要加载到NetworkX中的关系数据,并最终将其转换为加权图。NetworkX DiGraph()以图形()的边缘权重不加总和,如何加权?

本质上,关系边是有向和有权的,我想在我转换图时保留weight属性。使用下面的代码,我已经能够从字典中加载关系边缘到MultiDiGraph()

MG = nx.MultiDiGraph([(i['source'],i['target']) for i in edges ]) 

然后,我转换MultiDiGraph()DiGraph(),并重复边缘凝结成一个,并更新边的权重每个边缘:

G = nx.DiGraph() 
for (u,v) in MG.edges(): 
    G.add_edge(u, v, weight=len(MG[u][v])) 

从这里,我想给DiGraph()转换为Graph(),又保留并凝结在边缘重量:

g = G.to_undirected() 

但我的问题是,它似乎保留为'a' -> 'b''b' -> 'a'找到的第一个边缘权重。

我想要的是这些边缘的总和作为去向无向边时的权重。

下面是一个示例展示一下我的工作:

# relational directed edge data containing duplicate edges 
edges = [{'source': 'a', 'target': 'b'}, 
     {'source': 'a', 'target': 'b'}, 
     {'source': 'a', 'target': 'b'}, 
     {'source': 'b', 'target': 'a'}, 
     {'source': 'a', 'target': 'c'}, 
     {'source': 'c', 'target': 'a'}, 
     {'source': 'c', 'target': 'd'}, 
     {'source': 'c', 'target': 'd'}, 
     {'source': 'd', 'target': 'c'}] 

# load edges into a MultiDiGraph to maintain direction and duplicate edges 
MG = nx.MultiDiGraph([(i['source'],i['target']) for i in edges ]) 

MG.edges(data=True) = [('a', 'c', {}), 
         ('a', 'b', {}), 
         ('a', 'b', {}), 
         ('a', 'b', {}), 
         ('c', 'a', {}), 
         ('c', 'd', {}), 
         ('c', 'd', {}), 
         ('b', 'a', {}), 
         ('d', 'c', {})] 

# convert MultiDiGraph to a DiGraph and update edge weight 
G = nx.DiGraph() 
for (u,v) in MG.edges(): 
    G.add_edge(u, v, weight=len(MG[u][v])) 

G.edges(data=True) = [('a', 'c', {'weight': 1}), 
         ('a', 'b', {'weight': 3}), 
         ('c', 'a', {'weight': 1}), 
         ('c', 'd', {'weight': 2}), 
         ('b', 'a', {'weight': 1}), 
         ('d', 'c', {'weight': 1})] 

# convert DiGraph to a Graph, but edge weight not updated as sum, but first value 
g = G.to_undirected() 

g.edges(data=True) = [('a', 'c', {'weight': 1}), 
         ('a', 'b', {'weight': 1}), 
         ('c', 'd', {'weight': 1})] 

最后,我想在无向图边的权重是如下,但如果我无法弄清楚这是G.to_undirected或如何一个选项来做到这一点:

g.edges(data=True) = [('a', 'c', {'weight': 2}), 
         ('a', 'b', {'weight': 4}), 
         ('c', 'd', {'weight': 3})] 

回答

1

G.to_undirected()不能用于控制哪些数据的无向边弄,看到networkx docs

您可以改为执行以下操作:

import networkx as nx 

G = nx.DiGraph() 
G.add_edges_from([('a', 'c', {'weight': 1}), 
        ('a', 'b', {'weight': 3}), 
        ('c', 'a', {'weight': 1}), 
        ('c', 'd', {'weight': 2}), 
        ('b', 'a', {'weight': 1}), 
        ('d', 'c', {'weight': 1})]) 

print G.edges(data=True) 

g = nx.Graph() 
g.add_edges_from(G.edges_iter(), weight=0) 

print g.edges(data=True) 

for u, v, d in G.edges_iter(data=True): 
    g[u][v]['weight'] += d['weight'] 

print g.edges(data=True) 

基本上,你创建一个新的无向图G,并有向图G.所有边缘填充它在这一点上,你也初始化边缘权重最后,您只需将权重添加到无向图中的每个边。请注意,在无向图中,边(u,v)与(v,u)相同。

+0

我使用你的方式,但如果我添加相同的边缘,结果是不正确的。例如,如果我再加一个'('a','c',{'weight':1})',print g.edges(data = True)''将会是'[('a','c ',{'weight':2}),('a','b',{'weight':4}),('c','d',{'weight':3})]'。这是相同的输出。它应该不是'[''','c',{'weight':3}),('a','b',{'weight':4}),('c','d ',{'weight':3})]'? – 2017-01-06 07:35:10