Python 如何通过切片范围有效地索引到一维numpy数组
我有一个大的一维数据数组。我有一个Python 如何通过切片范围有效地索引到一维numpy数组,python,arrays,numpy,slice,Python,Arrays,Numpy,Slice,我有一个大的一维数据数组。我有一个开始索引数组,索引到发生重要事件的数据中。我想得到一个范围数组,这样我就可以得到长度为L的窗口,在开始时的每个起始点都有一个窗口。虚假样本数据: data = np.linspace(0,10,50) starts = np.array([0,10,21]) length = 5 我想本能地做一些事情,比如 data[starts:starts+length] 但实际上,我需要将开始转换为范围“窗口”的2D数组。从函数语言开始,我会将其视为从列表到列表的映射
开始
索引数组,索引到发生重要事件的数据中。我想得到一个范围数组,这样我就可以得到长度为L
的窗口,在开始时的每个起始点都有一个窗口。虚假样本数据:
data = np.linspace(0,10,50)
starts = np.array([0,10,21])
length = 5
我想本能地做一些事情,比如
data[starts:starts+length]
但实际上,我需要将开始
转换为范围“窗口”的2D数组。从函数语言开始,我会将其视为从列表到列表的映射,如:
np.apply_along_axis(lambda i: np.arange(i,i+length), 0, starts)
但这不起作用,因为apply\u沿轴
只允许标量返回值
您可以这样做:
pairs = np.vstack([starts, starts + length]).T
ranges = np.apply_along_axis(lambda p: np.arange(*p), 1, pairs)
data[ranges]
或者,您也可以使用列表:
data[np.array([np.arange(i,i+length) for i in starts])]
或者你可以迭代地做。(呜呜)
有没有一种简洁、惯用的方法可以在这样的起点切入数组?(请原谅我这个新手的愚蠢。)
要实现这一点,您可以使用NumPy.meshgrid()
,如下所述
正如hpaulj在评论中指出的,这个问题实际上不需要网格,因为可以使用阵列广播
返回
array([[ 0. , 0.20408163, 0.40816327, 0.6122449 , 0.81632653],
[ 2.04081633, 2.24489796, 2.44897959, 2.65306122, 2.85714286],
[ 4.28571429, 4.48979592, 4.69387755, 4.89795918, 5.10204082]])
如果需要花费大量时间,可以使用as_stried()
来创建数据的滑动窗口数组
data = np.linspace(0,10,50000)
length = 5
starts = np.random.randint(0, len(data)-length, 10000)
from numpy.lib.stride_tricks import as_strided
sliding_window = as_strided(data, (len(data) - length + 1, length),
(data.itemsize, data.itemsize))
然后您可以使用:
sliding_window[starts]
得到你想要的
它也比创建索引数组快。注意:这与问题不同-该问题的长度不规则。在这里,我所做的应该适合普通的矩形数组。很好的一个,+1从我这里——据我所知,这是最简洁优雅的方法。index=np.arange(length)+start[:,None]
也works@hpaulj啊!那要平滑得多。更新答案。
data = np.linspace(0,10,50000)
length = 5
starts = np.random.randint(0, len(data)-length, 10000)
from numpy.lib.stride_tricks import as_strided
sliding_window = as_strided(data, (len(data) - length + 1, length),
(data.itemsize, data.itemsize))
sliding_window[starts]