Numpy切片函数:从数组形状(X,2)动态创建切片索引np.r_ [a:b,c:d,…]以在数组中选择

问题描述 投票:3回答:2

情况

我有代表双通道音频的2D阵列。我想创建一个函数,该函数在任意位置(例如仅语音部分)返回此数组的片段。当我将值明确写入np.r_

时,我已经知道该怎么做。

样本数据

arr = np.arange(0,24).reshape((2, -1))
# array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
#        [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

输入

A x宽度为2的长度数组,例如

selector = np.array([[0, 2], [6, 9]])
# array([[0, 2],
#        [6, 9]])

所需的输出

# create an indexed arrays
selection_indices = np.r_[0:2, 6:9]
# array([0, 1, 6, 7, 8])

# use indices to select 2D
arr[:, selection_indices]
# array([[ 0,  1,  6,  7,  8],
#        [12, 13, 18, 19, 20]])

目标

一个采用宽度为2的X长度数组(形状:X,2)的函数,表示切片的开始和结束,并使用该函数返回对数组的选择。有效的np.r_[0:2, 6:9],但随后是一个参数。

arr = np.arange(0,24).reshape((2, -1))

def slice_returner(arr, selector):
    # something like this (broken); should be like: np.r_[0:2, 6:9]
    selection_indices = np.r_[[row[0]:row[1]] for row in selector]
    # return 2D slice
    return arr[:, selection_indices]

selector = np.array([[0, 2], [6, 9]])
sliced_arr = slice_returner(arr, selector)

如何将输入转换为选择切片?最好使用最少的数组创建/复制。

python arrays python-3.x numpy slice
2个回答
2
投票

认为布尔索引可能是一种有效的方法。因此,我们可以创建一个掩码,然后索引cols并获得输出-

# Generate mask for cols
mask = np.zeros(arr.shape[1],dtype=bool)
for (i,j) in selector:
    mask[i:j] = True

# Boolean index into cols for final o/p
out = arr[:,mask]

内存开销仅仅是掩码,它是一个布尔数组,应该是最小的,而最终输出则是必需的。

矢量化蒙版创建

[如果selector中有很多条目,则有一种基于广播的矢量化方法来创建col的掩码,像这样-

r = np.arange(arr.shape[1])
mask = ((selector[:,0,None]<=r) & (selector[:,1,None]>r)).any(0)

1
投票

您可以只根据单个范围创建索引数组

slices = [[0, 2], [6, 9]]
np.concatenate([np.arange(*i) for i in slices])
# array([0, 1, 6, 7, 8])

并使用它来提取数据

arr[:, np.concatenate([np.arange(*i) for i in slices])]
# array([[ 0,  1,  6,  7,  8],
#        [12, 13, 18, 19, 20]])
© www.soinside.com 2019 - 2024. All rights reserved.