Python 2d numpy,有效地将非零索引[row,col]指定为[row,row]和[col,col]中的最小值

Python 2d numpy,有效地将非零索引[row,col]指定为[row,row]和[col,col]中的最小值,python,numpy,matrix,linear-algebra,Python,Numpy,Matrix,Linear Algebra,我使用一个矩阵来计算图中节点之间的关系组合(细节无关) 我有一个N*N邻接矩阵,行和列对应于节点。所以,位置[5,7]是节点5和节点7的次数。如[7,5]所示。位置[3,3]是节点3出现的次数,因此它总共出现了多少次 在每个循环中,我必须减少我的矩阵。取一个大小为n的向量,用这个向量减去矩阵对角线。因此,我减少了每个节点的总计数:比如矩阵中的[1,1]和[2,2]和[3,3]等等 希望到目前为止我能说得通。这是一个问题 此时,我修改了矩阵的对角线。现在,我想修改每个位置[I,j],其中 i !=

我使用一个矩阵来计算图中节点之间的关系组合(细节无关)

我有一个N*N邻接矩阵,行和列对应于节点。所以,位置[5,7]是节点5和节点7的次数。如[7,5]所示。位置[3,3]是节点3出现的次数,因此它总共出现了多少次

在每个循环中,我必须减少我的矩阵。取一个大小为n的向量,用这个向量减去矩阵对角线。因此,我减少了每个节点的总计数:比如矩阵中的[1,1]和[2,2]和[3,3]等等

希望到目前为止我能说得通。这是一个问题

此时,我修改了矩阵的对角线。现在,我想修改每个位置[I,j],其中

i != j and matrix[i,j] != 0  
我想对其进行修改,以便:

matrix[i,j] = min(matrix[i,i],matrix[j][j])
当然,现在我可以迭代每个索引对(I,j),然后做我上面写的。但这是缓慢的。我希望有一些聪明的数学或numpy技巧,使这更快


谢谢大家!

首先,在进行任何优化之前,您应该先分析一下:在程序的整个生命周期中只需要几十毫秒,或者只占总运行时间的一小部分的事情上,尝试聪明点是没有意义的

也就是说,您可以通过利用广播将最小值的使用矢量化:

def slow(arr):
    out = arr.copy()
    for (i, j), x in np.ndenumerate(arr):
        if i != j and arr[i,j] != 0:
            out[i,j] = min(arr[i, i], arr[j, j])
    return out

def fast(arr):
    diag = arr.diagonal()
    mins = np.minimum(diag, diag[:, None])
    out = np.where(arr != 0, mins, arr)
    out[np.diag_indices_from(arr)] = diag
    return out
这让我

In [61]: a = np.random.randint(0, 10, (100, 100))

In [62]: (slow(a) == fast(a)).all()
Out[62]: True

In [63]: %timeit slow(a)
11.9 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [64]: %timeit fast(a)
62.8 µs ± 916 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

首先,在进行任何优化之前,您应该先分析一下:对于在整个程序生命周期中只需要几十毫秒,或者只占总运行时间的一小部分的事情,您没有必要尝试巧妙地处理

也就是说,您可以通过利用广播将最小值的使用矢量化:

def slow(arr):
    out = arr.copy()
    for (i, j), x in np.ndenumerate(arr):
        if i != j and arr[i,j] != 0:
            out[i,j] = min(arr[i, i], arr[j, j])
    return out

def fast(arr):
    diag = arr.diagonal()
    mins = np.minimum(diag, diag[:, None])
    out = np.where(arr != 0, mins, arr)
    out[np.diag_indices_from(arr)] = diag
    return out
这让我

In [61]: a = np.random.randint(0, 10, (100, 100))

In [62]: (slow(a) == fast(a)).all()
Out[62]: True

In [63]: %timeit slow(a)
11.9 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [64]: %timeit fast(a)
62.8 µs ± 916 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

谢谢你的建议,你是对的,我应该先让它工作,然后再配置文件。我这么做了很多次,我很有信心加速会很大,但这并不能改变你是正确的。无论如何,谢谢你简洁的回答!谢谢你的建议,你是对的,我应该先让它工作,然后再配置文件。我这么做了很多次,我很有信心加速会很大,但这并不能改变你是正确的。无论如何,谢谢你简洁的回答!