numpy:获取大小相同的多个范围子集

时间:2017-11-19 13:38:15

标签: python numpy

我正在寻找什么

# 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方式。

1 个答案:

答案 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都指向原始数组中的相同内存位置。这就是为什么这个解决方案应该非常有效。