【问题标题】:Python: How to return a list of connected nodesPython:如何返回连接节点的列表
【发布时间】:2017-07-29 07:48:01
【问题描述】:

我有一组节点(存储为nodes = np.array([[x1,y1],[x2,y2],etc]]))和连接节点的元素。每个元素都是两个节点索引的数组。

所以[0,3]是连接节点0和3的元素。

如何返回连接到给定节点索引的所有节点索引的列表?

例如,如果:

element = np.array( [ [3,2] , [1,4] , [1,3] ])
print findConnectedNodes(3) 

应该打印 [2,1]

【问题讨论】:

    标签: python numpy search


    【解决方案1】:

    这是一个可行的解决方案:

    import numpy as np
    
    elements = np.array([[3, 2], [1, 4], [1, 3]])
    
    def findConnectedNodes(lookup):
        connected = [x for y in elements for x in y if lookup in y]
        return list(set(connected) - {lookup,})
    
    print(findConnectedNodes(3))  # [1, 2]
    

    它的工作原理是获取所有具有我们正在寻找的节点的列表并将它们展平。然后,它将展平列表转换为集合以删除重复项,最后删除节点查找节点。

    【讨论】:

      【解决方案2】:

      使用 numpy,您可以遍历所有元素并返回包含目标节点的那些元素。然后您创建一组这些数字并从该集合中删除目标节点,例如

      def findconnected_nodes(a, element):   
          return np.setdiff1d(np.unique([i for i in element if a in i]), a)
      

      编辑

      比较两种有效解决方案的性能:

      element = np.random.randint(1,10,(10000, 2))
      a = 2
      %timeit findConnectedNodes(a, element)
      

      10 个循环,3 个循环中的最佳值:每个循环 51.9 毫秒

      %timeit findconnected_nodes(a, element)
      

      100 个循环,3 个循环中的最佳:每个循环 16.6 毫秒

      【讨论】:

        【解决方案3】:

        如果您正在寻找需要的功能:

        data = np.array([[3,2], [1,4], [1,3]])
        

        然后返回:

        [2, 1]
        

        你可以拥有:

        res = []
        matches = d[(d == 3).any(axis = 1)]
        for pair in matches:
            for node in pair:
                if (node != 3):
                    res.append(node)
        

        或者简单地说:

        matches = data[(data == 3).any(axis = 1)]
        [node for pair in matches for node in pair if node != 3]
        

        see this for double list comprehension.

        【讨论】:

        • 您的代码返回 [2, 1, 4, 1] 这对于问题是错误的。
        【解决方案4】:

        这是一种矢量化方法 -

        def findConnectedNodes(a, node_id = 3):
            b = a[(a == node_id).any(1)]
            return b[b!=node_id]
        

        示例运行 -

        In [40]: element
        Out[40]: 
        array([[3, 2],
               [1, 4],
               [1, 3]])
        
        In [41]: findConnectedNodes(element, node_id=3)
        Out[41]: array([2, 1])
        
        In [42]: findConnectedNodes(element, node_id=1)
        Out[42]: array([4, 3])
        
        In [43]: findConnectedNodes(element, node_id=2)
        Out[43]: array([3])
        

        为了提高性能,我们可以使用切片来获得b,以获得这样一个两列输入数组的成对节点。此外,我们可以在这里使用更多的布尔掩码。因此,我们将有另外两种方法,就像这样 -

        def findConnectedNodes_v2(a, node_id = 3):
            b = a[(a[:,0] == node_id) | (a[:,1] == node_id)]
            return b[b!=node_id]
        
        def findConnectedNodes_v3(a, node_id = 3):
            mask2D = a == node_id
            mask1D = mask2D[:,0] | mask2D[:,1]
            return a[mask1D][~mask2D[mask1D]]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-19
          • 2021-07-24
          • 2016-12-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多