2012-01-17 12 views
23

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.Concatenar dos matrices numpy en la 4ta dimensión

Por ejemplo:

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

Para aclarar, deseo c[:,:,:,0] y c[:,:,:,1] que corresponden a las dos matrices originales.

Respuesta

4

¿Qué hay de

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

Esta función se agregó en la versión numpy 1.10 y hace que esta operación sea más elegante. –

1

Esto funciona para mí:

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

A pesar de que sería bueno si funcionaba su camino, también.

+0

lo he intentado, pero el resultado es un (2 x 3 x 4 x 5) matriz. Cerca, pero no del todo. –

12

¿Qué hay de lo siguiente:

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

Esto da una (3 x 4 x 5 x 2) conjunto, que creo que se presenta en la forma que usted requiere.

Aquí, None es sinónimo de np.newaxis: Numpy: Should I use newaxis or None?

edición Según lo sugerido por @ Joe Kington, el código podría ser limpiado un poco mediante el uso de una elipsis:

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

me ganó un par de segundos. . .dammit :-) Lo culpo a escribir 'np.newaxis', en lugar de' None' +1 a usted – JoshAdel

+0

@JoshAdel: LOL, ¡pero ha guardado al no tener que escribir todos esos dos puntos molestos! :-) – NPE

+0

Funciona como un encanto. –

27

Aquí ir:

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) 
+3

Aceptando este por ser un poco más legible. Además, me deshizo de mi ignorancia del operador '...'. –

+7

Si tiene una secuencia de matrices que desea apilar de esta manera, puede usar: 'c = np.concatenate ([aux [..., np.newaxis] para aux en sequence_of_arrays], axis = 3)' –

+6

Más en general, puede usar 'axis = -1' independientemente del número de dimensiones en la matriz original. –

0

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

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

en el pasado.

8

La respuesta aceptada arriba es genial. Pero agregaré lo siguiente porque soy un idiota matemático y es un buen uso del hecho de que a.shape es a.T.shape[::-1] ... es decir. tomar una transposición invierte el orden de los índices de una matriz numpy. Así que si usted tiene sus bloques de construcción de bloques de una matriz llamada, entonces la solución anterior es:

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

pero también se podía hacer

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

que creo que se lee más limpiamente. Vale la pena señalar que la respuesta aceptada ya a ejecutar con mayor rapidez:

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

Esa es una solución encantadora y creativa. –

+0

Esto es lo que necesitaba y es independiente del número total de dimensiones para cualquier matriz numpy. ¡Gracias! – rayryeng

Cuestiones relacionadas