根据先前的索引在每个索引处更新numpy

时间:2018-11-23 20:35:48

标签: python 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]没有上一个元素。通过在矩阵前面添加一个额外的0和0列,可以轻松解决此问题。

2 个答案:

答案 0 :(得分:3)

这是向量化的一种方法:

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()应该可以加快速度。

答案 1 :(得分:1)

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

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

这将创建两个新副本。需要零填充,因为roll重新引入了“滚动”超出边界的元素:

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]