通过避免for循环从节点列表构建邻接矩阵 结论最终解决方案输出

如何解决通过避免for循环从节点列表构建邻接矩阵 结论最终解决方案输出

我需要解决什么?

从索引列表构建二进制矩阵。 这是我继续的方式,但我想获得一种避免循环的有效方法

输入:

list_indices =[
[0,3,4],[2,1,0],[3,5]
]

预期输出

results=[
[0,[1,[0,1],]

结果对应于由索引列表构成的二进制邻接(对称)矩阵。结果中的1对应于属于list_indices的同一行的一对索引。

list_indices中的对为:

row 1 : (0,3),(3,0),(0,4),(4,3)
row 2 : (0,1),(1,(2,2),1)
row 3 : (3,5),(5,3)


number of column and number of rows in results = np.max(list_indices)+1=6 

我尝试了什么?

results=np.zeros((np.max(list_indices)+1,np.max(list_indices)+1))

for pair in itertools.combinations(list_indices,r=2) :
                      
         results[pair[0],pair[1]]=results[pair[1],pair[0]]=1.0

有效的构建方式是什么? (避免循环)

itertools.combinations返回一个成对列表,然后将其用于填充矩阵结果。由于矩阵是对称的,因此itertools.combinations提供了与上对角线矩阵相对应的对列表。对角线设置为零

解决方法

这个问题与我在discussed前10天的调查密切相关,因此,我将在此处发布最重要发现的摘要。

  • 将社区存储为长度不平衡的列表会强制使用效率低下的迭代或串联。相反,您可以使用单个数组,计数如下:

        flow = [0,3,4,2,1,5]
        counts = [3,2]
    
  • 单一组合的一种更快的方法是使用np.triu_indices方法,而不是itertools.combinations

    def combs(t):
         x,y = np.triu_indices(len(t),1)
         return np.transpose([t[x],t[y]])
    

    在我的解决方案中指出,您正在寻找如何避免以下情况的串联和列表理解:

    np.concatenate([combs(n) for n in list_indices])
    

    或者({from itertools import*):

    np.array(list(chain(*[combinations(n,2) for n in list_indices])))
    
  • 根据您的输入,我发现了几种矢量化方法:

    def repeat_blocks(a,sizes,repeats):
        #Thanks @Divakar: https://stackoverflow.com/a/51156138/3044825
        r1 = np.repeat(np.arange(len(sizes)),repeats)
        N = (sizes*repeats).sum() # or np.dot(sizes,repeats)
        id_ar = np.ones(N,dtype=int)
        id_ar[0] = 0
        insert_index = sizes[r1[:-1]].cumsum()
        insert_val = (1-sizes)[r1[:-1]]
        insert_val[r1[1:] != r1[:-1]] = 1
        id_ar[insert_index] = insert_val
        out = a[id_ar.cumsum()] 
        return out
    
    def concat_combs1(flow,counts):
        #way 1 based on repetition of blocks of consecutive items
        col1 = repeat_blocks(flow,counts,counts)
        col2 = np.repeat(flow,np.repeat(counts,counts))
        return np.transpose([col1,col2])[col1 < col2]
    
    def concat_combs2(targets,counts):
        #way 2 based on repetition of blocks dissociated from each other
        counts = list(map(len,targets))
        col1 = np.concatenate(np.repeat(targets,axis=0))
        col2 = np.repeat(np.concatenate(targets),col2])[col1 < col2]
    

    测试:

    list_indices = [np.array([0,4]),np.array([2,0]),np.array([3,5])]
    flow = np.array([0,5])
    counts = np.array([3,2])
    # Usage:
    np.concatenate([combs(n) for n in list_indices])
    concat_combs1(flow,counts)
    concat_combs2(list_indices)
    

    输出:

    array([[0,3],[0,4],[3,[1,2],1],5]])
    

结论

已在perfplotigraph.Graph.Barabasi(n = x,m = 3)启用了四个方法,包括itertools.combinationsnp.triu_indices。该图的每个顶点平均有3个邻居。总之,connection of repeated consecutive blocks效果最好。这次,numpy数组的连接比链接组合要慢,因为要串联的小列表数量很大。

enter image description here

最终解决方案

为了以最快的方式构建入射矩阵,您需要应用concat_combs1方法的小变化:

flow = np.array([0,2])
results = np.zeros((np.max(flow)+1,np.max(flow)+1),dtype=int)
col1 = repeat_blocks(flow,counts)
col2 = np.repeat(flow,counts))
results[col1,col2] = 1
np.fill_diagonal(results,0)

输出

[[0 1 1 1 1 0]
 [1 0 1 0 0 0]
 [1 1 0 0 0 0]
 [1 0 0 0 1 1]
 [1 0 0 1 0 0]
 [0 0 0 1 0 0]]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?