我想以矢量化方式同时在两个轴上实现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中进行矢量化,以便仅需对数组求和一次?
答案 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
的连续调用进行性能测试时,我会尽量记住发布规格。