Numpy:如何将(N,)维向量作为沿 D 轴的新元素插入到(N,M,D)维数组中? (N, M, D+1)

Numpy: how to insert an (N,) dimensional vector to an (N, M, D) dimensional array as new elements along the D axis? (N, M, D+1)

a 是形状为 (N, M, D) == (20, 4096, 6).

的数组

b 是一个形状为 (N,) == (20,).

的数组

我想将 b 的值插入到 a 中,这样 b 中的每个值都按元素附加到 D 暗淡的 aa 中的第 7 个元素)。

所以 c 将是这样一个数组,形状为 (20, 4096, 7),其中 c[i,:,-1] == b[i] 代表所有 ic[...,:-1] == a.

我知道您可以创建一个新数组并相应地添加值,例如:

N, M, D = a.shape # (20, 4096, 6)
c = np.zeros((N, M, D+1))
c[...,:-1] = a
for i in range(N):
    c[i,:,-1] = b[i]

但想知道这里的 numpy 向导是否有更巧妙的方法来使用 numpy 操作而不使用中间数组。

在扩展到 3D 后沿第二个轴复制 b,然后沿最后一个轴与 a 连接 -

b_rep = np.repeat(b[:,None,None],a.shape[1],axis=1)
out = np.concatenate((a, b_rep,axis=-1)

或者,我们可以使用 np.broadcast_to 创建复制版本:

b_rep = np.broadcast_to(b[:,None,None], (len(b), a.shape[1],1)

这是另一个one-liner

np.r_['2,3,0', a, np.broadcast_to(b, (a.T.shape[1:])).T]

此外,我想提一下,您的原始方法实际上接近(或至少是)推荐的方法。只需使用 empty 代替 zeros 并使用广播代替循环:

res = np.empty((N,M,D+1), np.promote_types(a.dtype, b.dtype))
res[..., :-1], res[..., -1] = a, b[:, None]

...

而且 - 只是为了好玩 - 还有一个,我明确不推荐。 不要使用这个!

np.where(np.arange(D+1)<D, np.lib.stride_tricks.as_strided(a, (N,M,D+1), a.strides), b[:, None, None])