根据上一个索引更新每个索引的numpy



是否有一种矢量化的方法可以根据numpy数组中任意索引之前的索引来更新它?例如,在伪代码中,如果我有矩阵

1 2 3
3 1 4
1 3 2

对于每个索引(i,j(,我想做:

m[i,j] += max(m[i, j-1], m[i-1, j])

现在我知道我可以迭代地做到这一点,但我想知道是否有一种矢量化的方法可以做到这一步,因为这比一次又一次地将其从numpy数据空间中取出更有效。

此外,我知道这是一个围栏张贴问题,因为m[0]没有以前的元素。这很容易通过在矩阵前面加一行和一列0来解决。

这里有一种可以将其矢量化的方法:

arr = np.array([[1, 2, 3],[3, 1, 4],[1, 3, 2]])
arr_A = np.roll(arr, 1, axis=0)
arr_B = np.roll(arr, 1, axis=1)
max_val = np.maximum(arr_A, arr_B)
output = arr + max_val
>>> [[4 5 5]
[7 4 7]
[4 4 6]]

请注意,这对上面的代码给出了不同的答案,因为编写代码的方式意味着每次循环后都会更新值。如果您想要这样做,那么就必须使用for循环。

>>> [[ 4  6  9] # Output after updating the matrix in each loop.
[ 7  8 13]
[ 8 11 15]]

如果你正在寻找一种类似的算法,而不是试图恢复这个确切的输出,那么np.roll()应该能加快速度。

您可以使用numpy.roll创建矩阵的移位版本:

m += np.maximum(np.roll(m, 1, axis=0), np.roll(m, 1, axis=1))

不过这会创建两个新副本。需要零填充,因为滚动重新引入了"滚动"超出边界的元素:

p = np.pad(m, [(1, 1), (1, 1)], 'constant')
m += np.maximum(np.roll(p, 1, axis=0), np.roll(p, 1, axis=1))[1:-1, 1:-1]

最新更新