Skip to main content
 首页 » 编程设计

python之按 block 切片 numpy 数组

2025年05月04日20daizhj

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

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元素,加入aa的N3元素
  3. 重复2.直到aa用完

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

请您参考如下方法:

简单地 reshape 为 2D 并切片前 N3 列 -

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

当N3超过N2

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

from skimage.util.shape import view_as_windows 
 
starts = np.arange(len(aa), step=N2) 
lens = len(aa) - np.arange(len(aa), step=N2) 
rem_lens = lens[lens < N3] 
m0 = lens < N3 
 
l1 = N3*(~m0).sum() 
l2 = rem_lens.sum()  
out = np.empty(l1+l2, dtype=aa.dtype) 
out[:l1] = view_as_windows(aa,(N3))[::N2].ravel() 
rem_starts = starts[m0] 
ss = l1+np.r_[0,rem_lens.cumsum()] 
for s,i,j in zip(rem_starts, ss[:-1], ss[1:]): 
    out[i:j] = aa[s:]