N维数组‘Cut-and-overlap reduction’操作的高效实现问询
N维数组‘Cut-and-overlap reduction’操作的高效实现问询
注:我完全不知道该怎么称呼这个操作,所以暂时叫它“cut-and-overlap”。如果有公认的术语,请务必告诉我!
Intro
我现在需要实现一个能对N维数组执行的操作,下面会详细说明。我用的是Python的numpy库,想找这个生态里的数值工具库来实现,不过其他语言的实现方案我也感兴趣。虽然用循环写1D或2D的版本是可行的,但写起来挺麻烦的,而我需要至少支持4D数组的实现(不用太夸张,4D就行)。
有没有什么巧妙的方法能做到?比如用滑动窗口、扁平化或者重塑数组这类技巧?😉
操作说明
这个操作的核心是在数组上做若干“切割”,然后在切割位置把数组自身滑动重叠,最后对重叠部分的值做聚合。我这里用的是简单的求和。我觉得用例子说明最清楚,下面是1D和2D的示例,推广到N维应该也很直观。
示例
1D 案例
先给输入:
arr = [0,2,5,3,2,1,0,3,4,5,2,3,6,4,1,2,3] cut_locations = [4,7,12] slide_amount = [3,2,1]
数组会被切成这样:[0,2,5,3|2,1,0|3,4,5,2,3|6,4,1,2,3]
然后按指定的偏移量滑动重叠:
0253 210 34523 64123
最后把重叠部分求和,得到结果数组:[0,4,9,7,5,2,9,4,1,2,3]
2D 案例
2D的情况可视化起来稍微复杂点:
输入
输入是一个2D数组,在指定的行/列位置切割成多个块,每个块对应一个滑动偏移量
输出
每个切割后的块按偏移量滑动后重叠,重叠位置的值求和,得到最终的2D结果数组
边界情况
还有一种极端情况:滑动量超过数组长度。在我的应用场景里这种情况很少见,但确实可能发生。比如:
arr = [0,2,5,3,2,1,0,3,4,5,2,3,6,4,1,2,3] cut_locations = [5] slide_amount = [20]
结果是:[1,0,3,4,5,2,3,6,4,1,2,3,0,0,0,0,2,5,3,2]
适用于小偏移量的1D实现
我自己写了一个针对小偏移量的1D版本,代码如下:
import numpy as np def slide_and_overlap(arr, cut_locations, slide_amounts): right_pads = np.append(len(arr) - cut_locations, [0]) left_pads = np.append([0], cut_locations) chunks = np.split(arr, cut_locations) result = np.zeros(len(arr)) for i, chunk in enumerate(chunks): slide_amount = np.sum(np.append([0], slide_amounts)[:i+1]) padded_chunk = np.pad(chunk, (left_pads[i], right_pads[i]), mode='constant', constant_values=0) slid_chunk = np.roll(padded_chunk, -1*slide_amount) result += slid_chunk # Trim trailing zeros from right side result = np.trim_zeros(result, trim='b') return result
备注:内容来源于stack exchange,提问作者Heisenbugs
相关产品推荐
相关产品推荐

