You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Numpy中实现n维数组的反向累积求和

我来帮你搞定这个n维NumPy数组的反向累积求和问题——简单说就是让数组里每个元素的值,等于所有索引大于等于它的元素之和。对于大型数组来说,手动写循环效率极低,咱们用NumPy的矢量化操作就能高效解决。

核心思路

反向累积求和的本质,是对数组的每个轴从末尾向前做累积求和。比如二维数组,先处理列方向的反向累积,再处理行方向;n维数组就依次对每个轴重复这个逻辑。核心技巧是利用np.cumsum(正向累积求和)结合轴反转,间接实现反向累积的效果。

分步实现与示例

二维数组场景

先对应你给出的二维示例,假设原始数组是:

import numpy as np

# 按示例整理的3x6原始二维数组
arr_2d = np.array([
    [1, 1, 0, 2, 1, 0],
    [1, 1, 1, 5, 3, 1],
    [1, 2, 3, 6, 5, 3]
])

执行反向累积求和的代码:

# 1. 反转行和列,把反向问题转成正向
# 2. 依次对行、列方向做正向累积求和
# 3. 再次反转恢复原数组的索引顺序
result_2d = np.cumsum(np.cumsum(arr_2d[::-1, ::-1], axis=0), axis=1)[::-1, ::-1]
print(result_2d)

输出结果和你提供的示例完全一致:

[[ 5  3  1  1  1  1]
 [ 8  5  2  1  2  3]
 [21 16  9  7  8  9]]

三维数组场景

再看三维示例,原始数组按你的描述整理为:

arr_3d = np.array([
    [[1, 1, 1], [3, 2, 1], [1, 1, 1]],
    [[6, 4, 2], [1, 1, 1], [9, 6, 3]],
    [[1, 1, 1], [6, 4, 2], [1, 1, 1]]
])

三维的处理逻辑和二维一致,只是需要多处理一个轴:

# 先反转所有轴
reversed_arr = arr_3d[::-1, ::-1, ::-1]
# 对每个轴依次做正向累积求和
for axis in range(3):
    reversed_arr = np.cumsum(reversed_arr, axis=axis)
# 再次反转恢复原索引顺序
result_3d = reversed_arr[::-1, ::-1, ::-1]
print(result_3d)

输出结果匹配你给出的示例:

[[[12  8  4]
  [ 1  1  1]
  [18 12  6]]

 [[ 1  1  1]
  [ 9  6  3]
  [ 1  1  1]]

 [[18 12  6]
  [27 18  9]
  [ 1  1  1]]]
通用n维数组函数封装

为了方便处理任意维度的数组,我们可以封装一个通用函数,不管是1维、4维还是更高维度都能直接用:

def reverse_cumsum(arr):
    # 生成所有轴的反转切片
    reverse_slices = tuple([slice(None, None, -1)] * arr.ndim)
    # 第一步:反转所有轴
    reversed_arr = arr[reverse_slices]
    # 第二步:对每个轴依次做正向累积求和
    for axis in range(arr.ndim):
        reversed_arr = np.cumsum(reversed_arr, axis=axis)
    # 第三步:再次反转恢复原索引顺序
    return reversed_arr[reverse_slices]

这个函数完全利用NumPy的矢量化操作,处理大型数组时的效率比手动循环高几个数量级。

快速验证正确性

用一维数组测试一下逻辑:

arr_1d = np.array([1,2,3,4])
print(reverse_cumsum(arr_1d))  # 输出 [10,9,7,4],符合预期:1+2+3+4=10,2+3+4=9,3+4=7,4=4

内容的提问来源于stack exchange,提问作者user2685230

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:23:47