水平拼接的高效方式

时间:2019-03-19 10:08:50

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

我有两个(大)阵列。为了说明起见,我在下面使用一个简单的示例:

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的尺寸),也许使用广播,那就太好了!


PS 。之所以要避免这种复制,是因为内存需求呈线性增长:

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

1 个答案:

答案 0 :(得分: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]])