Python 按块切片numpy数组
我需要对一个数组(Python 按块切片numpy数组,python,numpy,slice,Python,Numpy,Slice,我需要对一个数组(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: aa 跳转N2元素并添加aa 重复2。直到aa耗尽 我可
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
:
aa
N2
元素并添加aa
aa
耗尽aa[i*N2:(i*N2)+N3]
存储一组数组切片是切片数的线性时间。在NumPy中执行该循环(因此在C循环中而不是Python循环中,假设您使用的是CPython)会快一点。但除非你有大量的切片,否则这可能无关紧要
但是,使用list(aa[i*N2:[i*N2)+N3])
将每个片段转换为一个列表,然后扩展现有列表,速度非常慢。这可能会占用你99%以上的时间,所以优化另外1%的时间是无关紧要的。NumPy无法加速将每个片段转换为列表
因此,如果您实际上不需要列表,请停止调用list
。您可以只使用数组列表,并根据需要将它们链接在一起,也可以从数组列表中构建,或者只将原始数组转换为所需的形状
如果你真的需要一个列表,那就太慢了,而且你也无能为力。你可以使用NumPy,或者更简单地做同样的事情
然而,它可能不会显著提高效率
使用aa[i*N2:(i*N2)+N3]
存储一组数组切片是切片数的线性时间。在NumPy中执行该循环(因此在C循环中而不是Python循环中,假设您使用的是CPython)会快一点。但除非你有大量的切片,否则这可能无关紧要
但是,使用list(aa[i*N2:[i*N2)+N3])
将每个片段转换为一个列表,然后扩展现有列表,速度非常慢。这可能会占用你99%以上的时间,所以优化另外1%的时间是无关紧要的。NumPy无法加速将每个片段转换为列表
因此,如果您实际上不需要列表,请停止调用list
。您可以只使用数组列表,并根据需要将它们链接在一起,也可以从数组列表中构建,或者只将原始数组转换为所需的形状
如果您确实需要一个列表,那么它本身就很慢,而且您对此无能为力。只需将其重塑为
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:]
从skimage.util.shape导入视图作为窗口
启动=np.arange(len(aa),步骤=N2)
透镜=透镜(aa)-np.arange(透镜(aa),阶跃=N2)
rem_透镜=透镜[透镜
只需重塑为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:]
从skimage.util.shape导入视图作为窗口
启动=np.arange(len(aa),步骤=N2)
透镜=透镜(aa)-np.arange(透镜(aa),阶跃=N2)
rem_透镜=透镜[透镜
通过重塑阵列,您可以更优雅地完成此操作。首先将初始阵列设置为二维:
N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., (N1, N2))
现在只需沿着第二维度移除一块大小为N3
的块:
bb = aa[:, :N3]
如果您需要bb
保持平坦,请这样做:
bb = aa[:, :N3].ravel()
通过重塑阵列,您可以更优雅地执行此操作。首先将初始阵列设置为二维:
N1, N2, N3 = 200, 500000, 30
aa = np.random.uniform(0., 1., (N1, N2))
现在只需沿着第二维度移除一块大小为N3
的块:
bb = aa[:, :N3]
如果您需要bb
保持平坦,请这样做:
bb = aa[:, :N3].ravel()
你为什么在这里做
列表(…)
,而不是直接使用aa[i*N2:(i*N2)+N3]
?切片是非常有效的,你可以用numpy使它变得简单一点,但不会更快。但是,将每个片段转换为列表的速度非常慢,numpy不会做任何事情来加快速度。你是说跳过N2-N3元素吗?@abarnert对不起,你说的“直接使用aa[]
是什么意思?我使用list将这个块添加到最终的bb
数组中。如果我不这样做,我将只是添加元素,而不是扩展列表。@Gabriel为什么希望最终结果是列表?为什么不让它成为一个数组链,或者一个跨步数组呢?我不知道,这正是我发现的连接元素块的方法。为什么你在这里做列表(…)
,而不是仅仅