将二维数组附加到一个单一的数组中。

4
我可以帮您翻译成中文:

我有一个循环遍历2维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得到与l1相同的结果?
3个回答

4

只需使用以下代码:

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

或者使用其他人描述的许多辅助函数(如dstack,hstack,concatenate)。编辑:我发现上述两种解决方案非常易读且接近Python列表语法,但这是非常主观的。计算其速度时,您会发现这两个解决方案比基于concatenate提出的最快解决方案稍微快一些。此外请注意,这不会创建视图。

1
确实,对于大型数组来说,这比我的建议快得多。 - unutbu

3
这里有一种方法可以从数组中生成该输出:
>>> 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数组无法在内存中动态增长。这些操作会导致复制数组,并用更大的数组填充新的内存块。如果数组很大,这可能效率低下。


这对于numpy的新手来说是非常好的信息。然而请注意,这些解决方案都没有提供所需的输出。 - gg349
1
@gg349 你说得很�� - 我读错了问题。我会删除这个答案,并在有机会时尝试修复。谢谢! - Alex Riley
1
我认为答案应该保留,这对于提问者来说是有价值的信息。 - gg349
我不确定。使用 dstack 时,你应该从 1,2 开始,而不是 1,5 - gg349
1
是的,这是正确的——如果数据需要以特定方式在内存中布局,那么copy('C')数组是必要的。因此,出于这个原因以及速度差异(dstack较慢),我更喜欢你和ubutnu的方法而不是我提出的方法。 - Alex Riley
显示剩余2条评论

3
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连接,并产生至少三维的结果。
或者,使用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

在一般情况下,如果要进行重塑操作,您需要编写np.concatenate([a1, b1]).reshape((2,a1.shape[0],-1))。但我认为这并不更易读。 - gg349
1
@gg349:确实,可读性是主观的。对我来说,“concatenate/reshape”只是更易读,因为我比使用带有特殊指令的'0,3'r_更频繁(我必须查找以记住如何使用)。 - unutbu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接