如何在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
相关产品推荐
相关产品推荐

