繁体   English   中英

合并或加入numpy数组

[英]Combine or join numpy arrays

我如何加入两个numpy ndarray来快速完成以下任务,使用优化的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  ]])

显然,你想要的是水平堆叠的ab的笛卡尔积。 您可以使用itertools模块为numpy数组生成索引,然后使用numpy.hstack来堆叠它们:

import numpy as np
from itertools import product

a = np.array([[ 0.09028802,  0.2274419 ],
              [ 0.35402772,  0.87834376]])

b = np.array([[ 0.4776325 ,  0.73690098],
              [ 0.69181444,  0.672248  ],
              [ 0.79941110,  0.52273   ]])

a_inds, b_inds = map(list, zip(*product(range(len(a)), range(len(b)))))

c = np.hstack((a[a_inds], b[b_inds]))

这导致c

array([[ 0.09028802,  0.2274419 ,  0.4776325 ,  0.73690098],
       [ 0.09028802,  0.2274419 ,  0.69181444,  0.672248  ],
       [ 0.09028802,  0.2274419 ,  0.7994111 ,  0.52273   ],
       [ 0.35402772,  0.87834376,  0.4776325 ,  0.73690098],
       [ 0.35402772,  0.87834376,  0.69181444,  0.672248  ],
       [ 0.35402772,  0.87834376,  0.7994111 ,  0.52273   ]])

打破指数的事情:

product(range(len(a)), range(len(b))如果将其转换为列表,将生成如下所示的内容:

[(0, 0), (0, 1), (1, 0), (1, 1)]

你想要这样的东西: [0, 0, 1, 1][0, 1, 0, 1] ,所以你需要转置生成器。 执行此操作的惯用方法是使用zip(*zipped_thing) 但是,如果您只是直接分配这些,您将获得tuples ,如下所示:

[(0, 0, 1, 1), (0, 1, 0, 1)]

但numpy数组将元组解释为多维索引,因此您希望将它们转换为列表,这就是我将list构造函数映射到product函数的结果的原因。

不是最漂亮的,但你可以结合hstackrepeattile

>>> a = np.arange(4).reshape(2,2)
>>> b = a+10
>>> a
array([[0, 1],
       [2, 3]])
>>> b
array([[10, 11],
       [12, 13]])
>>> np.hstack([np.repeat(a,len(a),0),np.tile(b,(len(b),1))])
array([[ 0,  1, 10, 11],
       [ 0,  1, 12, 13],
       [ 2,  3, 10, 11],
       [ 2,  3, 12, 13]])

或者对于3x3案例:

>>> a = np.arange(9).reshape(3,3)
>>> b = a+10
>>> np.hstack([np.repeat(a,len(a),0),np.tile(b,(len(b),1))])
array([[ 0,  1,  2, 10, 11, 12],
       [ 0,  1,  2, 13, 14, 15],
       [ 0,  1,  2, 16, 17, 18],
       [ 3,  4,  5, 10, 11, 12],
       [ 3,  4,  5, 13, 14, 15],
       [ 3,  4,  5, 16, 17, 18],
       [ 6,  7,  8, 10, 11, 12],
       [ 6,  7,  8, 13, 14, 15],
       [ 6,  7,  8, 16, 17, 18]])

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

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

ma,na = a.shape
mb,nb = b.shape

(2)接下来,初始化一个3D数组,其列数是输入数组ab中列数的总和。 使用np.empty执行此任务。

out = np.empty((ma,mb,na+nb),dtype=a.dtype)

(3)然后,从设置3D阵列用于与所述行中的第一“NA”列的第一轴线a具有a[:,None,:] 因此,如果我们将它分配给out[:,:,:na] ,那么第二个冒号将向NumPy表明我们需要一个广播设置,如果可能的话,NumPy数组中的单例dims总是会发生。 实际上,这与平铺/重复相同,但可能以有效的方式。

out[:,:,:na] = a[:,None,:]

(4)重复将b元素设置为输出数组。 这一次,我们将沿着第一轴广播outout[:,:,na:] ,与第一个冒号帮助我们做广播。

out[:,:,na:] = b

(5)最后一步是将输出重新整形为2D形状。 这可以通过简单地用所需的2D形状元组改变形状来完成。 重塑仅改变视图,实际上是零成本。

out.shape = (ma*mb,na+nb)

冷凝一切,完整的实现将如下所示 -

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)

您可以使用dstack()broadcast_arrays()

import numpy as np

a = np.random.randint(0, 10, (3, 2))
b = np.random.randint(10, 20, (4, 2))

np.dstack(np.broadcast_arrays(a[:, None], b)).reshape(-1, a.shape[-1] + b.shape[-1])

尝试使用np.hstack或np.vstack。 即使对于长度不同的数组,这也适用。 您需要做的就是:np.hstack(attachedarray [:])或np.vstack(attachedarray [:])

所有数组都是可索引的,因此您可以通过调用来合并:

a[:2],b[:2]

或者您可以使用核心numpy堆叠功能,应该看起来像这样:

c = np.vstack(a,b)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM