将二维数组附加到一个数组

Append 2 dimensional arrays to one single array

我在二维 np.arrays() 上有一个循环,我需要将这些数组添加到一个数组中。

简单地说Python我会这样做

In [37]: a1 = [[1,2],[3,4]]

In [38]: b1 = [[5,6],[7,8]]

In [39]: l1 = []

In [40]: l1.append(a1)

In [41]: l1.append(b1)

In [42]: l1
Out[42]: [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

如何使用 numpy for l1 获得相同的结果?

只需使用:

l1 = np.array([a1,b1])

另请注意,在 numpy 中,您不会附加到数组。你先分配它们,然后再填充它们:

import numpy as np
a1 = np.array([[1,2],[3,4]])
b1 = np.array([[5,6],[7,8]])
#allocate exact size of the final array
l1 = empty(((2,)+a1.shape),dtype=a1.dtype)
l1[0]=a1
l1[1]=b1

或者您使用许多辅助函数之一(dstackhstackconcatenate 由其他人描述)

编辑:我发现上面的两个解决方案都非常易读并且接近 python 列出语法,但这是相当主观的。计算这有多快,您会发现这两种解决方案都比@unutbu 基于连接提出的最快解决方案快一点。此外请注意,这不会创建视图。

这是从数组中生成该输出的一种方法:

>>> np.dstack((a1,b1)).transpose(2,0,1)

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

       [[ 5,  6],
        [ 7,  8]],

np.dstack 生成一个 3D 数组,但轴需要以不同的顺序读取。我们希望轴的顺序 (0, 1, 2) 更改为 (2, 0, 1),因此需要转置和交换轴。


以下是有关连接数组的可能有用但不是直接相关的信息。 (在指出我对问题的误解之前输入。)

连接数组的一种方法是使用 np.concatenate:

>>> np.concatenate((a1, b1))
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

这将一个堆叠在另一个下方。您还可以使用 np.concatenate((a1, b1), axis=1) 并排连接数组。 (可以将两个以上的数组传递给函数。)

还有其他函数可以做到这一点;以上两个操作可以分别用np.vstack((a1,b1))np.hstack((a1,b1))来完成。

如果你想加入一个3D数组中的数组,你可以使用np.dstack((a1,b1)):

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

       [[3, 7],
        [4, 8]]])

请记住,与 Python 列表不同,Numpy 数组不能在内存中动态增长。这些操作导致数组被复制,并用更大的数组填充新的内存块。如果数组很大,这可能效率低下。

a1 = np.array([[1,2],[3,4]])
b1 = np.array([[5,6],[7,8]])
l1 = np.r_['0,3', a1, b1]

产量

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

       [[5, 6],
        [7, 8]]])

特殊指令 '0,3' 告诉 np.r_ 沿 axis=0 连接并产生至少具有 3 个维度的结果。


或者,使用 concatenatereshape 可读性更好,速度更快:

l1 = np.concatenate([a1, b1]).reshape((2,)+a1.shape))

In [111]: a2 = np.tile(a1, (10000,1))

In [112]: b2 = np.tile(b1, (10000,1))

In [113]: %timeit np.r_['0,3', a2, b2].shape
10000 loops, best of 3: 62.4 µs per loop

In [114]: %timeit np.concatenate([a2, b2]).reshape((2,)+a2.shape)
10000 loops, best of 3: 39.8 µs per loop