一次访问 numpy 数组中的块

2023-12-03

提供了一个 numpy 数组:

arr = np.array([0,1,2,3,4,5,6,7,8,9,10,11,12])

我想知道如何访问选择的大小chunks选择分离,连接和切片:

例如:获取由两个值分隔的大小为 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])

最有效的方法是什么?如果可能的话,我想尽可能避免复制或创建新对象。或许内存视图这里有帮助吗?


方法#1

这是一个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元素-

# 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一次访问 numpy 数组中的块 的相关文章

随机推荐