Python手动计算数组累加和与np.cumsum结果不一致的原因
问题原因
两者结果不一致的核心原因是手动实现的计算逻辑和np.cumsum的标准前缀和定义存在两处偏差:
首先明确测试用的数组x执行reshape后是3行3列的二维数组:
x = np.array([[ 1, -2, 0], [-2, 5, 0], [ 0, 0, 2]])
两者的计算逻辑差异
np.cumsum(x, axis=1)的标准逻辑:按行计算前缀和时,第k列(索引从0开始)的返回值是当前行从第0列到第k列(包含第k列)的所有元素累加结果。运行后得到的x1结果为:x1 = array([[ 1, -1, -1], [-2, 3, 3], [ 0, 0, 2]])- 手动实现的循环逻辑存在两个问题:
- 切片范围不符合前缀和要求:Python切片
x[:,:k]遵循左闭右开规则,只会取前k列(即索引0到k-1的列,不包含第k列),累加结果整体比标准前缀和右移了一位,第0列因为x[:,:0]是空数组,计算结果全为0。 - 列遍历不完整:循环k的取值范围是
0,1,2,当k=2时x[:,:2]只会取前2列(索引0、1),完全没有累加第2列的元素,导致最后一列结果缺失。
原代码运行后得到的x2结果为:
x2 = array([[ 0., 1., -1.], [ 0., -2., 3.], [ 0., 0., 0.]]) - 切片范围不符合前缀和要求:Python切片
修正方法
如果要让手动计算结果和np.cumsum完全一致,只需要把切片的结束索引改为k+1,保证每一步累加都包含当前第k列的元素,同时覆盖所有列:
x2 = np.zeros(x.shape) for k in range(x.shape[1]): x2[:,k] = np.sum(x[:,:k+1],axis=1)
如果你原本想要实现的是「前缀和最前面补0、用于后续差分计算」的逻辑,只需要调整cumsum的写法即可匹配原有手动结果:
x1 = np.zeros((x.shape[0], x.shape[1]+1)) x1[:, 1:] = np.cumsum(x, axis=1) # 取x1[:, :-1]即可得到和原手动代码一致的x2结果
内容的提问来源于stack exchange,提问作者John Stone
相关产品推荐
相关产品推荐

