python - 从一维 numpy 数组中有效地切片窗口,围绕第二个二维数组给出的索引

标签 python arrays numpy optimization indexing

我想从同一个一维 numpy 数组中提取多个切片,其中切片索引是从随机分布中提取的。基本上,我想实现以下目标:

import numpy as np
import numpy.random

# generate some 1D data
data = np.random.randn(500)

# window size (slices are 2*winsize long)
winsize = 60

# number of slices to take from the data
inds_size = (100, 200)

# get random integers that function as indices into the data
inds = np.random.randint(low=winsize, high=len(data)-winsize, size=inds_size)

# now I want to extract slices of data, running from inds[0,0]-60 to inds[0,0]+60
sliced_data = np.zeros( (winsize*2,) + inds_size )
for k in range(inds_size[0]):
    for l in range(inds_size[1]):
        sliced_data[:,k,l] = data[inds[k,l]-winsize:inds[k,l]+winsize]

# sliced_data.shape is now (120, 100, 200)

上面的嵌套循环工作正常,但速度很慢。在我的真实代码中,我将需要为比这些大得多的数据数组执行数千次。有什么方法可以更有效地做到这一点?

请注意,在我的例子中,inds 将始终是二维的,但在获得切片后,我将始终对这两个维度之一求和,因此一种仅在一个维度上累积总和的方法会好的。

我找到了 this questionthis answer这看起来几乎是一样的。然而,问题只是关于一维索引向量(而不是我的二维)。此外,答案缺少一些上下文,因为我不太了解建议的 as_strided 是如何工作的。由于我的问题似乎并不少见,我想我会再问一次,希望能得到一个更具解释性的答案,而不仅仅是代码。

最佳答案

以这种方式使用 as_strided 似乎比 Divakar 的方法要快一些(这里是 20 毫秒对 35 毫秒),尽管内存使用可能是个问题。

data_wins = as_strided(data, shape=(data.size - 2*winsize + 1, 2*winsize), strides=(8, 8))
inds = np.random.randint(low=0, high=data.size - 2*winsize, size=inds_size)
sliced = data_wins[inds]
sliced = sliced.transpose((2, 0, 1))    # to use the same index order as before

Strides是每个维度中索引的字节步长。例如,对于形状为 (x, y, z) 的数组和大小为 d(对于 float64 为 8)的数据类型,步幅通常为 (y*z*d, z*d, d),以便第二个索引遍历 z 项的整行。将两个值都设置为 8,data_wins[i, j]data_wins[j, i] 将引用相同的内存位置。

>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>> a = np.arange(10, dtype=np.int8)
>>> as_strided(a, shape=(3, 10 - 2), strides=(1, 1))
array([[0, 1, 2, 3, 4, 5, 6, 7],
       [1, 2, 3, 4, 5, 6, 7, 8],
       [2, 3, 4, 5, 6, 7, 8, 9]], dtype=int8)

关于python - 从一维 numpy 数组中有效地切片窗口,围绕第二个二维数组给出的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34182307/

相关文章:

javascript - 在数组中搜索字符串 - 返回 -1

python - 使用数量时如何指定单位的标量乘数?

python - 使用 beautifulSoup 抓取 <a href> 中的文本时,结果变为空

python - 如何测试对象是否为 pandas 日期时间索引?

arrays - 从 JSON 数组列表中检索未知的键名和值

python - 如何根据每行的第二个值将Python多维numpy数组导出到不同的文件?

python - 使用 python 在 numpy 数组中加载 tiff 堆栈

python - Numpy 数组大于 RAM : write to disk or out-of-core solution?

python - 如何在 Python 中测试命令行应用程序?

algorithm - GNU 模拟退火