Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按块切片numpy数组_Python_Numpy_Slice - Fatal编程技术网

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
  • 重复2。直到
    aa
    耗尽
  • 我可以通过numpy索引更快地执行此过程吗?

    您可以使用numpy,或者更简单地执行相同的操作

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

    使用
    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为什么希望最终结果是列表?为什么不让它成为一个数组链,或者一个跨步数组呢?我不知道,这正是我发现的连接元素块的方法。为什么你在这里做
    列表(…)
    ,而不是仅仅