用numpy数组加速按索引获取边矩阵

2024-10-06 06:59:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我想切割原始矩阵的边缘,想知道有没有更快的方法。因为我需要用相同的位置和位置多次运行selectEdge函数,这意味着索引对于许多图形都不会改变?有没有可能生成一个可以解决所有问题的映射矩阵?在

非常感谢

def selectEdge(positions, positions_u, originalMat, selectedMat):
    """ select Edge by neighbors of all points
    many to many
    m positions
    n positions
    would have m*n edges
    update selectedMat
    """
    for ele in positions:
        for ele_u in positions_u:            
            selectedMat[ele][ele_u] += originalMat[ele][ele_u]
            selectedMat[ele_u][ele] += originalMat[ele_u][ele]
    return selectedMat

我只需要上三角矩阵,因为它是对称的

^{pr2}$

这是我的测试结果

position, positions_u
[0 1 5 7] [2 3 4 6]
originalMat 
[[ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]]
selectedMat 
[[ 0.  0.  1.  1.  1.  0.  1.  0.]
 [ 0.  0.  1.  1.  1.  0.  1.  0.]
 [ 1.  1.  0.  0.  0.  1.  0.  1.]
 [ 1.  1.  0.  0.  0.  1.  0.  1.]
 [ 1.  1.  0.  0.  0.  1.  0.  1.]
 [ 0.  0.  1.  1.  1.  0.  1.  0.]
 [ 1.  1.  0.  0.  0.  1.  0.  1.]
 [ 0.  0.  1.  1.  1.  0.  1.  0.]]

对于后一种选择相邻边的实现,速度会更慢

def selectNeighborEdges(originalMat, selectedMat, relation):
    """ select Edge by neighbors of all points
    one to many
    Args:
        relation: dict, {node1:[node i, node j,...], node2:[node i, node j, ...]}

    update selectedMat
    """
    for key in relation:
        selectedMat = selectEdge([key], relation[key], originalMat, selectedMat)
    return selectedMat

Tags: keyinnodefordef矩阵selectmany
1条回答
网友
1楼 · 发布于 2024-10-06 06:59:20

您可以使用"advanced integer indexing"消除双for-loop

X, Y = positions[:,None], positions_u[None,:]
selectedMat[X, Y] += originalMat[X, Y]
selectedMat[Y, X] += originalMat[Y, X]

例如

^{pr2}$

首先检查selectEdgealt_selectEdge是否返回相同的结果:

expected = selectEdge(positions, positions_u, originalMat, selectedMat)
result = alt_selectEdge(positions, positions_u, originalMat, selectedMat)
assert np.allclose(expected, result)

下面是一个timeit基准测试(使用IPython):

In [89]: %timeit selectEdge(positions, positions_u, originalMat, selectedMat)
100 loops, best of 3: 4.44 ms per loop

In [90]: %timeit alt_selectEdge(positions, positions_u, originalMat, selectedMat)
10000 loops, best of 3: 104 µs per loop

相关问题 更多 >