我正在寻找什么
# I have an array
x = np.arange(0, 100)
# I have a size n
n = 10
# I have a random set of numbers
indexes = np.random.randint(n, 100, 10)
# What I want is a matrix where every row i is the i-th element of indexes plus the previous n elements
res = np.empty((len(indexes), n), int)
for (i, v) in np.ndenumerate(indexes):
res[i] = x[v-n:v]
重新制定,正如我在标题中所写,我正在寻找一种方法来获取初始数组的多个子集(相同大小)。
只是为了添加一个这个循环版本的细节,我想知道是否有一种以更优雅的方式实现这一目标的numpyish方式。
答案 0 :(得分:1)
以下是您所要求的。它使用numpy.lib.stride_tricks.as_strided
创建数据的特殊视图,可以按照所需的方式编制索引。
import numpy as np
from numpy.lib import stride_tricks
x = np.arange(100)
k = 10
i = np.random.randint(k, len(x)+1, size=(5,))
xx = stride_tricks.as_strided(x, strides=np.repeat(x.strides, 2), shape=(len(x)-k+1, k))
print(i)
print(xx[i-k])
示例输出:
[ 69 85 100 37 54]
[[59 60 61 62 63 64 65 66 67 68]
[75 76 77 78 79 80 81 82 83 84]
[90 91 92 93 94 95 96 97 98 99]
[27 28 29 30 31 32 33 34 35 36]
[44 45 46 47 48 49 50 51 52 53]]
一点解释。数组不仅存储数据,还存储小的标题"有布局信息。其中包括strides
,它告诉我们如何将线性内存转换为nd
。每个维度都有一个步幅,它只是可以找到沿该维度的下一个元素的偏移量。因此,2d数组的步幅是(行偏移,元素偏移)。 as_strided
允许直接操作数组strides
;通过将行偏移设置为与元素偏移相同,我们创建一个看起来像
0 1 2 ...
1 2 3 ...
2 3 4
. .
. .
. .
请注意,此阶段不会复制任何数据;例如,所有2
都指向原始数组中的相同内存位置。这就是为什么这个解决方案应该非常有效。