组合或连接 numpy 数组

Hel*_*rld 5 python arrays performance numpy vectorization

如何加入两个 numpy ndarrays 以快速完成以下操作,使用优化的 numpy,没有任何循环?

>>> a = np.random.rand(2,2)
>>> a
array([[ 0.09028802,  0.2274419 ],
       [ 0.35402772,  0.87834376]])

>>> b = np.random.rand(2,2)
>>> b
array([[ 0.4776325 ,  0.73690098],
       [ 0.69181444,  0.672248  ]])

>>> c = ???
>>> c
array([[ 0.09028802,  0.2274419, 0.4776325 ,  0.73690098],
       [ 0.09028802,  0.2274419, 0.69181444,  0.672248  ],
       [ 0.35402772,  0.87834376, 0.4776325 ,  0.73690098],
       [ 0.35402772,  0.87834376, 0.69181444,  0.672248  ]])
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 2

让我们通过一个预期的解决方案来处理涉及不同形状数组的一般情况,并使用一些内嵌注释来解释所涉及的方法。

(1) 首先,我们存储输入数组的形状。

ma,na = a.shape
mb,nb = b.shape
Run Code Online (Sandbox Code Playgroud)

(2) 接下来,初始化一个 3D 数组,其列数为输入数组中的列数与 的a总和b。用于np.empty此任务。

out = np.empty((ma,mb,na+nb),dtype=a.dtype)
Run Code Online (Sandbox Code Playgroud)

a(3) 然后,将 3D 数组的第一个轴设置为第一个“na”列以及来自with的行a[:,None,:]。因此,如果我们将其分配给out[:,:,:na],第二个冒号将向 NumPy 指示我们需要一个广播设置,如果可能的话,就像 NumPy 数组中的单例暗淡一样。实际上,这与平铺/重复相同,但可能是一种有效的方式。

out[:,:,:na] = a[:,None,:]
Run Code Online (Sandbox Code Playgroud)

(4) 重复将元素设置b到输出数组中。这次我们将沿着outwith的第一个轴进行广播out[:,:,na:],第一个冒号帮助我们进行广播。

out[:,:,na:] = b
Run Code Online (Sandbox Code Playgroud)

(5) 最后一步是将输出重塑为 2D 形状。这可以通过简单地使用所需的 2D 形状元组更改形状来完成。重塑只是改变观点,而且实际上是零成本。

out.shape = (ma*mb,na+nb)
Run Code Online (Sandbox Code Playgroud)

浓缩所有内容,完整的实现将如下所示 -

ma,na = a.shape
mb,nb = b.shape
out = np.empty((ma,mb,na+nb),dtype=a.dtype)
out[:,:,:na] = a[:,None,:]
out[:,:,na:] = b
out.shape = (ma*mb,na+nb)
Run Code Online (Sandbox Code Playgroud)