如何将numpy数组分成更小的块/批,然后遍历它们

Leb*_*oth 7 python numpy pandas

假设我有这个numpy数组

[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
Run Code Online (Sandbox Code Playgroud)

我想分两批拆分,然后迭代:

[[1, 2, 3],      Batch 1
[4, 5, 6]]

[[7, 8, 9],      Batch 2
[10, 11, 12]]
Run Code Online (Sandbox Code Playgroud)

最简单的方法是什么?

编辑:我很抱歉我错过了这样的信息:一旦我打算继续进行迭代,原始数组将因为拆分和迭代批量而被销毁.批量迭代完成后,我需要从第一批再次重新启动,因此我应该保留原始数组不会被销毁.整个想法是与需要迭代批量的随机梯度下降算法一致.在一个典型的例子中,我可以进行100000次迭代For循环,只需要一次又一次地重放1000次.

piR*_*red 9

考虑数组 a

a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9],
              [10, 11, 12]])
Run Code Online (Sandbox Code Playgroud)

选项1
使用reshape//

a.reshape(a.shape[0] // 2, -1, a.shape[1])

array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
Run Code Online (Sandbox Code Playgroud)

选项2
如果您想要两个组而不是两个组

a.reshape(-1, 2, a.shape[1])

array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])
Run Code Online (Sandbox Code Playgroud)

选项3
使用发电机

def get_every_n(a, n=2):
    for i in range(a.shape[0] // 2):
        yield a[2*i:2*(i+1)]

for sa in get_every_n(a):
    print sa

[[1 2 3]
 [4 5 6]]
[[ 7  8  9]
 [10 11 12]]
Run Code Online (Sandbox Code Playgroud)


Div*_*kar 7

您可以使用numpy.split沿第一轴分割的n次数,其中n是所需批次的数量.因此,实现看起来像这样 -

np.split(arr,n,axis=0) # n is number of batches
Run Code Online (Sandbox Code Playgroud)

因为,默认值axis0它本身,所以我们可以跳过设置它.所以,我们只需要 -

np.split(arr,n)
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [132]: arr  # Input array of shape (10,3)
Out[132]: 
array([[170,  52, 204],
       [114, 235, 191],
       [ 63, 145, 171],
       [ 16,  97, 173],
       [197,  36, 246],
       [218,  75,  68],
       [223, 198,  84],
       [206, 211, 151],
       [187, 132,  18],
       [121, 212, 140]])

In [133]: np.split(arr,2) # Split into 2 batches
Out[133]: 
[array([[170,  52, 204],
        [114, 235, 191],
        [ 63, 145, 171],
        [ 16,  97, 173],
        [197,  36, 246]]), array([[218,  75,  68],
        [223, 198,  84],
        [206, 211, 151],
        [187, 132,  18],
        [121, 212, 140]])]

In [134]: np.split(arr,5) # Split into 5 batches
Out[134]: 
[array([[170,  52, 204],
        [114, 235, 191]]), array([[ 63, 145, 171],
        [ 16,  97, 173]]), array([[197,  36, 246],
        [218,  75,  68]]), array([[223, 198,  84],
        [206, 211, 151]]), array([[187, 132,  18],
        [121, 212, 140]])]
Run Code Online (Sandbox Code Playgroud)

  • @Leb_Broth 那么原始数组没有被破坏。因此,如果你这样做:“out = np.split(arr,n)”,我们将得到一个这样的批次列表,即列表“out”和“arr”中的数组不变。这是否澄清了您的担忧? (2认同)

guo*_*rui 7

为了避免错误“数组分割不会导致均等分割”,

np.array_split(arr, n, axis=0)
Run Code Online (Sandbox Code Playgroud)

比 好np.split(arr, n, axis=0)

例如,

a = np.array([[170,  52, 204],
              [114, 235, 191],
              [ 63, 145, 171],
              [ 16,  97, 173]])
Run Code Online (Sandbox Code Playgroud)

然后

print(np.array_split(a, 2))

[array([[170,  52, 204],
       [114, 235, 191]]), array([[ 63, 145, 171],
       [ 16,  97, 173]])]

print(np.array_split(a, 3))

[array([[170,  52, 204],
       [114, 235, 191]]), array([[ 63, 145, 171]]), array([[ 16,  97, 173]])]
Run Code Online (Sandbox Code Playgroud)

但是,由于不是整数,print(np.split(a, 3))因此会引发错误。4/3