在第四维度上连接两个numpy数组

30

我有两个三维Numpy数组(3 x 4 x 5),我希望将它们连接起来,使得结果变成一个四维数组(3 x 4 x 5 x 2)。在Matlab中,可以使用 cat(4, a, b) 来实现,但是在Numpy中却不行。

例如:

a = ones((3,4,5))
b = ones((3,4,5))
c = concatenate((a,b), axis=3) # error!

为了澄清,我希望c[:,:,:,0]c[:,:,:,1]对应于原始的两个数组。

6个回答

32

怎么样呢

c = np.stack((a,b), axis=3)

4
这个函数是在numpy版本1.10中添加的,使这个操作更加优雅。 - Marijn van Vliet

29

这里是您需要的:

import numpy as np
a = np.ones((3,4,5))
b = np.ones((3,4,5))
c = np.concatenate((a[...,np.newaxis],b[...,np.newaxis]),axis=3)

4
接受这个略微更易读的版本。此外,它使我不再对 ... 操作符感到无知了。 - Marijn van Vliet
7
如果您有一系列要堆叠的数组,可以使用以下方式:c = np.concatenate([aux[..., np.newaxis] for aux in sequence_of_arrays], axis=3) - Tom Pohl
7
通常情况下,您可以在原始数组中的任何维度上使用 axis=-1,而不管其具有多少维。 - 1''

14

以下怎么样:

c = concatenate((a[:,:,:,None],b[:,:,:,None]), axis=3)

这将提供一个(3 x 4 x 5 x 2)的数组,我认为它是按照你所需要的方式布局的。

在这里,Nonenp.newaxis是同义词:Numpy: Should I use newaxis or None?

编辑 如@Joe Kington所建议的那样,可以通过使用省略号来简化代码:

c = concatenate((a[...,None],b[...,None]), axis=3)

只比我慢了几秒钟...该死 :-) 我会把它归咎于打出了np.newaxis,而不是None。+1分给你 - JoshAdel
@JoshAdel:哈哈,但你省去了打那些烦人的冒号的时间! :-) - NPE

9
上面的被接受的答案非常好。但是我会补充一下,因为我是一个数学迷,这是一个很好的利用 a.shape 等于 a.T.shape[::-1] 的事实的方法...即,对一个 numpy 数组进行转置可以颠倒其索引的顺序。所以,如果你有一个名为 blocks 的数组存储了你的基本模块,则上面的解决方案如下:
new = np.concatenate([block[..., np.newaxis] for block in blocks],
                     axis=len(blocks[0].shape))

但你也可以这样做。
new2 = np.array([block.T for block in blocks]).T

我认为这种写法更加清晰易懂。值得注意的是,已经被接受的答案运行速度更快:

%%timeit
new = np.concatenate([block[..., np.newaxis] for block in blocks],
                     axis=len(blocks[0].shape))
1000 loops, best of 3: 321 µs per loop

%%timeit
new2 = np.array([block.T for block in blocks]).T
1000 loops, best of 3: 407 µs per loop

1
那是一个可爱、创意十足的解决方案。 - Marijn van Vliet
这正是我所需要的,而且它对于任何numpy数组的总维数都是不可知的。谢谢! - rayryeng

1
这对我有效:
 c = numpy.array([a,b])

虽然如果按照你的方式工作会很好,但这样也可以。


我尝试过了,但结果是一个(2 x 3 x 4 x 5)的数组。接近了,但还不太对。 - Marijn van Vliet

0

这不一定是最优雅的,但我已经使用了各种变化

c = rollaxis(array([a,b]), 0, 4)

过去。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接