从位于的numpy数组中选择多个切片

2024-05-17 04:33:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来同时从numpy数组中选择多个切片。假设我们有一个1D数据数组,并希望提取其中的三部分,如下所示:

data_extractions = []

for start_index in range(0, 3):
    data_extractions.append(data[start_index: start_index + 5])

之后data_extractions将是:

data_extractions = [
    data[0:5],
    data[1:6],
    data[2:7]
]

在没有for循环的情况下有没有办法执行上述操作?numpy中的某种索引方案,它允许我从数组中选择多个切片,并将它们作为多个数组返回,比如在n+1维数组中?


我想也许我可以复制我的数据,然后从每一行中选择一个范围,但是下面的代码抛出一个索引器错误

replicated_data = np.vstack([data] * 3)
data_extractions = replicated_data[[range(3)], [slice(0, 5), slice(1, 6), slice(2, 7)]

Tags: 数据方法innumpyfordataindex切片
3条回答

在本文中,有一种使用^{}strided-indexing scheme方法,它基本上在输入数组中创建一个视图,因此对于创建视图来说非常有效,并且作为一个视图占用的内存空间也很少。 此外,这也适用于具有通用维度数的nDarray。

以下是实现方法-

def strided_axis0(a, L):
    # Store the shape and strides info
    shp = a.shape
    s  = a.strides

    # Compute length of output array along the first axis
    nd0 = shp[0]-L+1

    # Setup shape and strides for use with np.lib.stride_tricks.as_strided
    # and get (n+1) dim output array
    shp_in = (nd0,L)+shp[1:]
    strd_in = (s[0],) + s
    return np.lib.stride_tricks.as_strided(a, shape=shp_in, strides=strd_in)

4D数组情况运行示例-

In [44]: a = np.random.randint(11,99,(10,4,2,3)) # Array

In [45]: L = 5      # Window length along the first axis

In [46]: out = strided_axis0(a, L)

In [47]: np.allclose(a[0:L], out[0])  # Verify outputs
Out[47]: True

In [48]: np.allclose(a[1:L+1], out[1])
Out[48]: True

In [49]: np.allclose(a[2:L+2], out[2])
Out[49]: True

您可以使用索引选择要放入适当形状的行。 例如:

 data = np.random.normal(size=(100,2,2,2))

 # Creating an array of row-indexes
 indexes = np.array([np.arange(0,5), np.arange(1,6), np.arange(2,7)])
 # data[indexes] will return an element of shape (3,5,2,2,2). Converting
 # to list happens along axis 0
 data_extractions = list(data[indexes])

 np.all(data_extractions[1] == s[1:6])
 True

stride_tricks可以做到

a = np.arange(10)
b = np.lib.stride_tricks.as_strided(a, (3, 5), 2 * a.strides)
b
# array([[0, 1, 2, 3, 4],
#        [1, 2, 3, 4, 5],
#        [2, 3, 4, 5, 6]])

请注意,b引用了与a相同的内存,实际上多次引用(例如,b[0, 1]b[1, 0]是相同的内存地址)。因此,在使用新结构之前复制是最安全的。

nd可以以类似的方式完成,例如2d->;4d

a = np.arange(16).reshape(4, 4)
b = np.lib.stride_tricks.as_strided(a, (3,3,2,2), 2*a.strides)
b.reshape(9,2,2) # this forces a copy
# array([[[ 0,  1],
#         [ 4,  5]],

#        [[ 1,  2],
#         [ 5,  6]],

#        [[ 2,  3],
#         [ 6,  7]],

#        [[ 4,  5],
#         [ 8,  9]],

#        [[ 5,  6],
#         [ 9, 10]],

#        [[ 6,  7],
#         [10, 11]],

#        [[ 8,  9],
#         [12, 13]],

#        [[ 9, 10],
#         [13, 14]],

#        [[10, 11],
#         [14, 15]]])

相关问题 更多 >