将numpy数组分块切片

2024-04-26 00:14:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要对数组(aa)进行切片,给定三个定义切片条件的值(N1, N2, N3),如下所示:

import numpy as np

N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., N1*N2)

bb = []
for i in range(N1):
    bb += list(aa[i * N2:(i * N2) + N3])

此代码按照以下规则生成一个新数组bb

  1. aa的第一个N3元素
  2. 跳转N2元素并添加N3元素的aa
  3. 重复2。直到aa用尽

我可以通过numpy索引更快地执行这个过程吗?在


Tags: importnumpy元素定义asnp切片random
3条回答

您可以使用NumPy的^{}^{}来更简单地执行相同的操作。在

然而,它的效率可能不会显著提高。在

aa[i * N2:(i * N2) + N3]存储一组数组切片是片数的线性时间。在NumPy中执行循环(因此在C循环中而不是Python循环中,假设您使用CPython)会更快一些。但除非你有大量的切片,否则这可能不重要。在

但是,使用list(aa[i * N2:(i * N2) + N3])将每个切片转换为一个列表,然后扩展现有列表,速度非常慢。它可能会占用你99%以上的时间,所以优化另外1%的时间是无关紧要的。NumPy无法加速将每个片段转换为列表。在

因此,如果您实际上不需要一个列表,只需停止调用list。您可以根据需要使用一个数组列表和chain它们一起使用,也可以从数组列表中生成a custom-strided array,或者将原始数组^{}放入所需形状。在

如果你真的需要一份清单,那就太慢了,而且你也无能为力。在

你可以通过重塑数组来做得更优雅。首先将初始数组设为2D:

N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., (N1, N2))

现在只需要沿着第二个维度移除一个大小为N3的块:

^{pr2}$

如果您需要bb保持平坦,请这样做:

bb = aa[:, :N3].ravel()

只需将形状改为2D并将第一个N3列切片-

bb = aa.reshape(N1,N2)[:,:N3].ravel()

N3超过N2

如果N3超过N2,那么这些{}将在迭代中有重叠。为了解决这种情况,我们可以创建滑动窗口,然后对行进行切片,直到我们有足够的长度,然后对剩余的窗口有一个循环-

^{pr2}$

相关问题 更多 >