numpy:采用大小相同的多个范围子集

  • 本文关键字:范围 子集 numpy 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 方法以更优雅的方式实现这一目标。

以下内容符合您的要求。它使用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都引用原始数组中的相同内存位置。这就是为什么这个解决方案应该非常有效。

最新更新