【问题标题】:Append 2 dimensional arrays to one single array将二维数组附加到一个数组
【发布时间】:2015-01-13 14:49:09
【问题描述】:

我有一个二维 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 获得相同的结果?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    只需使用:

    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 列表语法,但这是相当主观的。计算速度有多快,您会发现这两种解决方案都比@unutbu 提出的基于连接的最快解决方案略快。此外请注意,这不会创建视图。

    【讨论】:

    • 确实,这比我的建议快很多(对于大型数组)。
    【解决方案2】:

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

    >>> 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 你说的很对——我误读了这个问题。我将删除此答案,并在有机会时尝试修复。谢谢!
    • 我认为答案应该保留,这对 OP 来说是有价值的信息
    • @gg349 使用dstack 的答案提供了所需的输出,即使格式不同。
    • 是的,确实如此 - 如果需要在内存中以特定方式布置数据,则需要 copy('C') 数组。出于这个原因,以及速度差异(dstack 更慢),我更喜欢你的方法和 ubutnu 的方法,而不是我建议的方法。
    【解决方案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 连接,并产生至少具有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
    

    【讨论】:

    • 在一般情况下使用a1,b1 进行整形,你必须写np.concatenate([a1, b1]).reshape((2,a1.shape[0],-1))。我不觉得它更具可读性。
    • @gg349:确实,可读性是主观的。 concatenate/reshape 对我而言更易读,因为我比 r_ 更频繁地使用它们,并带有 '0,3' 之类的特殊指令(我必须抬头才能记住如何使用。)
    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 2016-03-18
    • 2020-10-08
    • 2021-12-31
    • 2021-10-29
    相关资源
    最近更新 更多