Concatenar dos matrices numpy en la 4ta dimensión

Tengo dos matrices numpy con tres dimensiones (3 x 4 x 5) y quiero concatenarlas para que el resultado tenga cuatro dimensiones (3 x 4 x 5 x 2). En Matlab, esto se puede hacer con cat(4, a, b) , pero no en Numpy.

Por ejemplo:

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

Para aclarar, deseo que c[:,:,:,0] c[:,:,:,1] correspondan con las dos matrices originales.

Qué pasa

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

Aqui tienes:

 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) 

¿Qué tal lo siguiente?

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

Esto da una matriz (3 x 4 x 5 x 2), que creo que está dispuesta de la manera que necesita.

Aquí, None es sinónimo de np.newaxis : Numpy: ¿Debo usar newaxis o None?

edit Según lo sugerido por @Joe Kington, el código se puede limpiar un poco usando puntos suspensivos:

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

La respuesta aceptada arriba es genial. Pero a.shape siguiente porque soy un idiota de matemáticas y es un buen uso del hecho de que a.shape es aTshape[::-1] … es decir, tomar una transposición invierte el orden de los índices de un número. formación. Entonces, si tiene sus bloques de construcción en una matriz llamada bloques, la solución anterior es:

 new = np.concatenate([block[..., np.newaxis] for block in blocks], axis=len(blocks[0].shape)) 

pero también podrías hacer

 new2 = np.array([block.T for block in blocks]).T 

que creo que lee más limpiamente Vale la pena señalar que la respuesta ya aceptada se ejecuta más rápidamente:

 %%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 

mientras

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

Esto funciona para mí:

  c = numpy.array([a,b]) 

Aunque sería bueno si funcionara a tu manera, también.

No es necesariamente el más elegante, pero he usado variaciones de

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

en el pasado.