【问题标题】:How can I get branch of a networkx graph from pandas dataframe in Python in the form of a new pandas dataframe?如何以新的熊猫数据框的形式从 Python 中的熊猫数据框获取 networkx 图的分支?
【发布时间】:2021-10-17 10:08:21
【问题描述】:

我有一个熊猫数据框df,如下所示:

From    To
0   Node1   Node2
1   Node1   Node3
2   Node2   Node4
3   Node2   Node5
4   Node3   Node6
5   Node3   Node7
6   Node4   Node8
7   Node5   Node9
8   Node6   Node10
9   Node7   Node11

df.to_dict() 是:

{'From': {0: 'Node1',
  1: 'Node1',
  2: 'Node2',
  3: 'Node2',
  4: 'Node3',
  5: 'Node3',
  6: 'Node4',
  7: 'Node5',
  8: 'Node6',
  9: 'Node7'},
 'To': {0: 'Node2',
  1: 'Node3',
  2: 'Node4',
  3: 'Node5',
  4: 'Node6',
  5: 'Node7',
  6: 'Node8',
  7: 'Node9',
  8: 'Node10',
  9: 'Node11'}}

我使用 networkx 包将这个 pandas 数据帧绘制为网络图,如下所示:

我想以新的 pandas 数据框的形式从此网络图中获取独特的场景/分支,如下所示:

  A B   C   D
0   Node1   Node2   Node4   Node8
1   Node1   Node2   Node5   Node9
2   Node1   Node3   Node6   Node10
3   Node1   Node3   Node7   Node11

怎么可能得到这个?

【问题讨论】:

    标签: python python-3.x pandas dataframe function


    【解决方案1】:

    您已经在使用 networkx,为什么不让它为您获取路径:

    import networkx as nx
    
    # create a digraph from your edges
    G = nx.from_pandas_edgelist( df, 'From', 'To', create_using=nx.DiGraph())
    root_node = 'Node1'
    leaf_nodes = df.To[~(df.To.isin(df.From))]
    
    # get all paths from leaf_nodes back to root_node
    paths = []
    for node in leaf_nodes:
        paths.append( nx.shortest_path(G, root_node, node) )
    result = pd.DataFrame(paths)
    

    结果:

           0      1      2       3
    0  Node1  Node2  Node4   Node8
    1  Node1  Node2  Node5   Node9
    2  Node1  Node3  Node6  Node10
    3  Node1  Node3  Node7  Node11
    

    【讨论】:

      【解决方案2】:

      您可以像 DFS 这样迭代图形,然后在每个迭代和返回路径上保存路径并转换为 DataFrame,如下所示:

      import pandas as pd
      
      df = pd.DataFrame({
                'From':['Node1','Node1', 'Node2', 'Node2', 'Node3', 'Node3', 'Node4', 'Node5', 'Node6', 'Node7'],
                'TO'  :['Node2','Node3', 'Node4', 'Node5', 'Node6', 'Node7', 'Node8', 'Node9', 'Node10', 'Node11']
              })
      
      fnl_result = []
      def svPath(path, node, df, lst_vst, fnl_result):
          for val in df.values:
              if val[0] == node:
                  path.append(val[1])
                  svPath(path, val[1], df, lst_vst, fnl_result)
          
          if not path[-1] in lst_vst:
              fnl_result.append([p for p in path])
          for p in path: lst_vst.add(p)
          path.pop()
          return
          
      lst_vst = set()
      svPath(['Node1'],'Node1', df, lst_vst, fnl_result)
      dfOut = pd.DataFrame(fnl_result, columns=['A','B','C','D'])
      

      输出:

      >>> dfOut
              A       B       C       D
      0   Node1   Node2   Node4   Node8
      1   Node1   Node2   Node5   Node9
      2   Node1   Node3   Node6   Node10
      3   Node1   Node3   Node7   Node11
      

      【讨论】:

        【解决方案3】:

        使用 networkx 包解决此问题的另一种方法。

        import networkx as nx
        G = nx.DiGraph()
        G.add_edges_from((r.From, r.To) for r in df.itertuples())
        roots = [n for (n, d) in G.in_degree if d == 0]
        print(roots)
        leafs = [n for (n, d) in G.out_degree if d == 0]
        print(leafs)
        pd.DataFrame(
            nx.algorithms.all_simple_paths(G, roots[0], leafs)
        )
        

        创建了一个有向图,并从df 将边添加到其中。节点 1 是 G 中唯一的节点,其中 in_degree 等于 0,即它是整个图的根。因此,roots 等于节点 0。

        leafs 表示有向图中 out_degree 等于 0 的节点,即 ["Node8", "Node9", "Node10", "Node11"]。

        nx.algorithms.all_simple_paths(G, roots[0], leafs) 提供从节点 1 开始到叶子中每个节点结束的所有路径的列表。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-28
          • 2021-06-02
          • 2020-12-07
          • 2018-10-02
          • 1970-01-01
          • 1970-01-01
          • 2015-07-08
          • 2019-05-03
          相关资源
          最近更新 更多