聚合MultiGraph中的边属性

时间:2019-10-25 10:33:09

标签: python networkx

我有一个图,其中两个节点之间有多个边,如下例所示。我想将满足条件的所有边缘聚合到一个边缘中。在示例中:如果一条边属于同一组,那么我想将该边合并为一个边,并向'freq'属性中添加1。

G = nx.MultiGraph()
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=4)

G.edges(data=True)
OUT: MultiEdgeDataView([(1, 2, {'group': 1, 'freq': 1}), (1, 2, {'group': 1, 'freq': 1}), (1, 2, {'group': 2, 'freq': 1}), (1, 2, {'group': 2, 'freq': 1}), (1, 2, {'group': 3, 'freq': 1})])

我想要的结果应该是:

OUT: MultiEdgeDataView([(1, 2, {'group': 1, 'freq': 2}), (1, 2, {'group': 2, 'freq': 2}), (1, 2, {'group': 3, 'freq': 1})])

1 个答案:

答案 0 :(得分:1)

该代码基本上适用于任意数量的边缘属性,并相应地更新频率。我添加了评论以更加清楚

import networkx as nx

G = nx.MultiGraph()
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=4)
G.edges(data=True)

def get_same_attrib_key(u, v, data, G1, G2):

    # First check if edge exists in new Graph
    if G2.has_edge(u, v) is None:
      return None

    # Get data for all edges between u and v
    new_edge_data = G2.get_edge_data(u, v)


    if new_edge_data:

      # This index will be used to update frequency in new graph
      idx = 0

      # For each edge between u and v, check the attributes
      for dict_attrs in new_edge_data:

        # Example 1: If G1 has edge from 1-->2 with data {'group': 1}
        # and G2 has edge from 1-->2 with data {'group': 1, 'freq': 2},
        # this if statement will return True
        #
        # Example 2: If G1 has edge from 1-->2 with data {'group': 1}
        # and G2 has edge from 1-->2 with data {'group': 1, 'freq': 2, 'xyz':3},
        # this if statement will return False
        if len(new_edge_data[dict_attrs].items()-data.items())==1:
          return idx
        idx +=1

    # No match found, hence return None
    return None

G_agg = nx.MultiGraph()
for u, v, data in G.edges(data=True):

    # Check if the current edge with same attribute dictionary 
    # exists in new Graph. This key is used for accessing data 
    # in Multigraphs. 
    key = get_same_attrib_key(u, v, data, G, G_agg)

    # Update frequency if same edge exists
    if key is not None:
        G_agg[u][v][key]['freq'] += 1

    # Else create a new edge with same data and a new key `freq` set to 1
    else:
        G_agg.add_edge(u, v, **dict({'freq': 1}, **data))

这将返回以下边缘: MultiEdgeDataView([(1, 2, {'freq': 2, 'group': 1}), (1, 2, {'freq': 2, 'group': 2}), (1, 2, {'freq': 2, 'group': 3}), (1, 2, {'freq': 1, 'group': 4})])

现在,假设您想添加任意数量的边缘属性键并获取频率,那么此代码仍然有效,例如下图所示:

G = nx.MultiGraph()
G.add_edge(1,2, group=1, other=5)  #<------This edge attribute is diff. from others
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=1)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=3)
G.add_edge(1,2, group=4)
G.add_edge(1,2, group=2)
G.add_edge(1,2, group=2)
G.edges(data=True)

此代码将输出以下边缘: MultiEdgeDataView([(1, 2, {'group': 1, 'other': 5}), (1, 2, {'group': 3}), (1, 2, {'group': 1}), (1, 2, {'group': 1}), (1, 2, {'group': 2}), (1, 2, {'group': 2}), (1, 2, {'group': 2}), (1, 2, {'group': 3}), (1, 2, {'group': 4}), (1, 2, {'group': 2}), (1, 2, {'group': 2})])

请注意,键为'other':5的边沿的频率为1,因为此属性在'group':1和1和2之间的边沿的任何其他组合中均不存在

您可以在this Google Colab notebook here中检查代码。