numpy:沿两个轴的矢量化累计总和

时间:2018-09-04 22:47:09

标签: python numpy

我想以矢量化方式同时在两个轴上实现numpy.cumsum的功能。也就是说,输出中任何单元格的值应为输入中相应单元格上方和左侧(包括左侧)的所有单元格的总和。

这等效于在第一个轴上依次应用cumsum,然后在另一个轴上依次应用:

>>> X = np.arange(25).reshape(5,5)
>>> X
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
>>> np.cumsum(np.cumsum(X, axis=0),axis=1)
array([[  0,   1,   3,   6,  10],
       [  5,  12,  21,  32,  45],
       [ 15,  33,  54,  78, 105],
       [ 30,  64, 102, 144, 190],
       [ 50, 105, 165, 230, 300]])

但是我认为这是一种相对低效的方法。

能否在numpy / Python中进行矢量化,以便仅需对数组求和一次?

1 个答案:

答案 0 :(得分:0)

可能有更好的解决方案,但可以使用numba.stencil

import numba
# Define some input array
x = np.arange(25).reshape(5,5)
# Pad the array to one cell width with 0
y = np.pad(x, 1, mode='constant', constant_values=0)

# Instantiate the output array
ii = np.zeros_like(y)

@numba.stencil
def integral_image(A, B):
    # A is the input array, B is the output
    return A[0,0] + B[-1,0] + B[0,-1] - B[-1,-1]

# Slice the output to get rid of padded cells
ii = integral_image(y, ii, out=ii)[1:-1,1:-1]

这将生成一个模板功能,该功能使用输入图像中的值以及输出中先前计算的值。在执行计算之前,需要将输出实例化为零数组,并且必须将其作为输出数组传递给模具函数,以便该函数可以访问以前计算的值。

我的主要问题是,它需要复制输入数组以填充它以供numba.stencil使用。似乎numba开发人员正在考虑在某个点添加用于边界处理的不同模式,但是目前有必要填充输入以便在每个单元上应用模板。

我也不确定这与x.cumsum(0).cumsum(1)相比要快多少。当我根据对np.cumsum的连续调用进行性能测试时,我会尽量记住发布规格。