python - 2d numpy,有效地分配非零索引 [row,col] [row,row] 和 [col,col] 的最小值
问题描述
我正在使用矩阵来计算图中节点之间的关系组合(细节无关紧要)。
我有一个 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)
推荐阅读
- javascript - 拖放 HTML5
- javascript - Javascript 可拖动
- bash - 使用解压缩工具绕过坏 CRC
- azure - 字符串 '0000-00-00' 不是有效的 AllXsd 值
- javascript - Javascript用用户输入替换对象列表中的键值
- excel - Excel VBA替换字符串中的第n个单词
- javascript - 如何在(点击)和(输入)事件上调用方法
- excel - 使用 FILTER 或类似公式定义数据验证列表
- django - AWS EB Django ModuleNotFoundError:没有名为“my_project”的模块
- appium - 无法验证“////apks/appium-uiautomator2-server-v4.15.0.apk”的签名