如何在不使用for循环的情况下,用可变起止索引切片numpy数组?
无循环实现Numpy多切片提取
当然可以不用for循环实现需求,以下是两种高效的实现方式:
方法一:索引广播法
利用Numpy的广播机制,直接生成所有切片的索引矩阵,再一次性提取元素:
import numpy as np a = np.random.randn(10) starts = np.array((1, 2)) ends = np.array((3, 4)) M = ends[0] - starts[0] # 所有切片长度一致,取任意一个计算即可 # 生成0到M-1的偏移量,形状为(1, M) offsets = np.arange(M)[None, :] # 通过广播将每个start值与偏移量相加,得到(N, M)的索引矩阵 indices = starts[:, None] + offsets # 一次性提取所有切片 all_slices = a[indices] print(all_slices.shape) # 输出 (2, 2)
原理:starts[:, None]将形状从(N,)转为(N,1),和形状(1,M)的offsets广播相加后,得到每个切片对应的所有索引,最后通过数组索引直接提取所有元素,完全避免循环。
方法二:滑动窗口视图法
使用Numpy内置的sliding_window_view工具,先生成所有长度为M的连续窗口,再直接选取对应start位置的窗口:
import numpy as np from numpy.lib.stride_tricks import sliding_window_view a = np.random.randn(10) starts = (1, 2) ends = (3, 4) M = ends[0] - starts[0] # 生成所有长度为M的连续滑动窗口,形状为(len(a)-M+1, M) windowed_a = sliding_window_view(a, window_size=M) # 选取starts对应的窗口 all_slices = windowed_a[starts] print(all_slices.shape) # 输出 (2, 2)
原理:sliding_window_view会创建原数组的视图(不占用额外内存),包含所有可能的连续M长度窗口。每个start值对应的窗口正好是a[start:start+M],直接索引即可得到目标数组,代码更简洁。
内容的提问来源于stack exchange,提问作者fuzzypants
相关产品推荐
相关产品推荐

