【问题标题】:Efficient way of horizontal concatenation without tiling无需平铺的水平连接的有效方式
【发布时间】:2019-08-09 19:48:15
【问题描述】:

我有两个(大)数组。出于说明目的,我使用下面的一个简单示例:

In [14]: arr1 = np.arange(32*512).reshape(32, 512)
In [15]: arr2 = np.arange(512).reshape(1, 512)

我想对这些数组进行水平串联(即沿轴 1 串联)。我想出了以下方法来实现这一点:

In [16]: np.hstack([arr1, np.tile(arr2, (arr1.shape[0], 1))]).shape
Out[16]: (32, 1024)

这按预期工作。但是,我想知道是否有任何其他有效的方法可以在不使用numpy.tile 的情况下进行这种连接。恐怕我会炸毁我的内存需求,因为数组真的很大。

如果可以避免这种重复的行(以匹配arr1 的尺寸),也许使用广播,那就太好了!


P.S.我之所以要避免这种复制是因为内存需求的线性增长:

In [20]: arr2.nbytes
Out[20]: 4096

In [19]: np.tile(arr2, (arr1.shape[0], 1)).nbytes
Out[19]: 131072

In [22]: arr1.shape[0] * arr2.nbytes
Out[22]: 131072

【问题讨论】:

    标签: python performance numpy numpy-ndarray array-broadcasting


    【解决方案1】:

    您可以预先分配和使用广播,但不会节省太多(我预计峰值内存使用量会下降大约四分之一):

    arr1 = np.arange(32*512).reshape(32, 512)
    arr2 = np.arange(512).reshape(1, 512)
    out = np.empty((32, 1024), arr1.dtype)
    out[:, :512] = arr1
    out[:, 512:] = arr2
    out
    #array([[    0,     1,     2, ...,   509,   510,   511],
    #       [  512,   513,   514, ...,   509,   510,   511],
    #       [ 1024,  1025,  1026, ...,   509,   510,   511],
    #       ...,
    #       [14848, 14849, 14850, ...,   509,   510,   511],
    #       [15360, 15361, 15362, ...,   509,   510,   511],
    #       [15872, 15873, 15874, ...,   509,   510,   511]])
    

    【讨论】:

    • 不错!我刚刚检查过,两种方法的最终内存要求是相同的,但是这种方法可能比我的要快得多,因为我们避免了显式复制..
    猜你喜欢
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 2018-06-29
    • 2022-12-08
    • 2020-12-04
    相关资源
    最近更新 更多