NetworkX DiGraph()到Graph()边缘权重没有求和,如何求和?

时间:2014-09-11 02:32:36

标签: python networkx

我有一些关系数据要加载到NetworkX中,最终将其转换为加权图。

本质上,关系边缘是有向和加权的,我想在转换图形时保留权重属性。使用以下代码,我已经能够将字典中的关系边缘加载到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 个答案:

答案 0 :(得分: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中的所有边缘填充它。此时,您还要初始化边缘'权重为0.最后,您只需将权重添加到无向图中的每条边。请注意,在无向图中,边(u,v)与(v,u)相同。