提供了一个 numpy 数组:
arr = np.array([0,1,2,3,4,5,6,7,8,9,10,11,12])
我想知道如何访问选定大小的块和选定的分隔符,包括连接和切片:
例如:获取由两个值分隔的大小为 3 的块:
arr_chunk_3_sep_2 = np.array([0,1,2,5,6,7,10,11,12]) arr_chunk_3_sep_2_in_slices = np.array([[0,1,2],[5,6,7],[10,11,12])
最有效的方法是什么?如果可能的话,我想尽可能避免复制或创建新对象。也许Memoryviews可以帮到你?
方法 #1
以下是其中的一个masking:
masking
def slice_grps(a, chunk, sep): N = chunk + sep return a[np.arange(len(a))%N < chunk]
样本运行 -
In [223]: arr Out[223]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) In [224]: slice_grps(arr, chunk=3, sep=2) Out[224]: array([ 0, 1, 2, 5, 6, 7, 10, 11, 12])
方法 #2
如果输入数组的最后一块有足够的跑道,我们可以,我们可以利用np.lib.stride_tricks.as_strided,受启发从每个元素块中this post选择元素-m``n
np.lib.stride_tricks.as_strided
this post
m``n
# https://stackoverflow.com/a/51640641/ @Divakar def skipped_view(a, m, n): s = a.strides[0] strided = np.lib.stride_tricks.as_strided shp = ((a.size+n-1)//n,n) return strided(a,shape=shp,strides=(n*s,s), writeable=False)[:,:m] out = skipped_view(arr,chunk,chunk+sep)
请注意,输出将是输入数组的视图,因此没有额外的内存开销并且实际上是免费的!
样本运行使事情变得清晰 -
In [255]: arr Out[255]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) In [256]: chunk = 3 In [257]: sep = 2 In [258]: skipped_view(arr,chunk,chunk+sep) Out[258]: array([[ 0, 1, 2], [ 5, 6, 7], [10, 11, 12]]) # Let's prove that the output is a view indeed In [259]: np.shares_memory(arr, skipped_view(arr,chunk,chunk+sep)) Out[259]: True