【问题标题】:Group connected graphs in pandas DF在 pandas DF 中对连接图进行分组
【发布时间】:2019-05-03 13:45:19
【问题描述】:

我有一个 pandas DF,其中每一列代表一个节点,两列代表一个边,如下所示:

 import pandas as pd
df = pd.DataFrame({'node1': ['2', '4','17', '17', '205', '208'],
               'node2': ['4', '13', '25', '38', '208', '300']})

所有节点都是无向的,即你可以从一个到另一个undirected_graph

我想将它们归为所有连接的组(Connectivity),如下:

df = pd.DataFrame({'node1': ['2', '4','17', '17', '205', '208'],
           'node2': ['4', '13', '25', '38', '208', '300']
            ,'desired_group': ['1', '1', '2', '2',  '3', '3']})

例如,之所以将前两行分组,是因为它可以从节点2到节点13(通过4)。

我设法找到的最接近的问题是这个: pandas - reshape dataframe to edge list according to column values 但据我了解,这是一个不同的问题。

在这方面的任何帮助都会很棒,在此先感谢。

【问题讨论】:

    标签: python pandas graph-theory


    【解决方案1】:

    使用networkxconnected_components

    import networkx as nx
    
    G=nx.from_pandas_edgelist(df, 'node1', 'node2')
    
    l=list(nx.connected_components(G))
    
    L=[dict.fromkeys(y,x) for x, y in enumerate(l)]
    
    d={k: v for d in L for k, v in d.items()}
    
    #df['New']=df.node1.map(d)
    df.node1.map(d)
    0    0
    1    0
    2    1
    3    1
    4    2
    5    2
    Name: node1, dtype: int64
    

    【讨论】:

    • 我真的很感动,只是检查它是否对我有用 :)
    【解决方案2】:

    如果由于某种原因你不能使用外部库,你可以实现算法:

    import pandas as pd
    
    
    def bfs(graph, start):
        visited, queue = set(), [start]
        while queue:
            vertex = queue.pop(0)
            if vertex not in visited:
                visited.add(vertex)
                queue.extend(graph[vertex] - visited)
        return visited
    
    
    def connected_components(G):
        seen = set()
        for v in G:
            if v not in seen:
                c = set(bfs(G, v))
                yield c
                seen.update(c)
    
    
    def graph(edge_list):
        result = {}
        for source, target in edge_list:
            result.setdefault(source, set()).add(target)
            result.setdefault(target, set()).add(source)
        return result
    
    
    df = pd.DataFrame({'node1': ['2', '4', '17', '17', '205', '208'],
                       'node2': ['4', '13', '25', '38', '208', '300']})
    
    G = graph(df[['node1', 'node2']].values)
    components = connected_components(G)
    lookup = {i: component for i, component in enumerate(components, 1)}
    df['group'] = [label for node in df.node1 for label, component in lookup.items() if node in component]
    print(df)
    

    输出

      node1 node2  group
    0     2     4      1
    1     4    13      1
    2    17    25      3
    3    17    38      3
    4   205   208      2
    5   208   300      2
    

    【讨论】:

    • 谢谢!生病看看,虽然我打算使用这个包
    猜你喜欢
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多