generando lote de clones a partir de la imagen numpy

Tengo una matriz numpy (una imagen) llamada a con este tamaño:

[3,128,192] 

ahora quiero crear una matriz numpy que contenga n copias de una que tenga esta dimensión:

 [n,3,128,192] 

¿Existe una función numpy que pueda ayudarme con este problema sin usar instrucciones de bucle?

Simplemente usa np.stack

 # say you need 10 copies of a 3D array `a` In [267]: n = 10 In [266]: np.stack([a]*n) 

Alternativamente, debería usar np.concatenate si está realmente preocupado por el rendimiento.

 In [285]: np.concatenate([a[np.newaxis, :, :]]*n) 

Ejemplo:

 In [268]: a Out[268]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]], [[16, 17, 18, 19], [20, 21, 22, 23], [24, 25, 26, 27], [28, 29, 30, 31]], [[32, 33, 34, 35], [36, 37, 38, 39], [40, 41, 42, 43], [44, 45, 46, 47]]]) In [271]: a.shape Out[271]: (3, 4, 4) In [269]: n = 10 In [270]: np.stack([a]*n).shape Out[270]: (10, 3, 4, 4) In [285]: np.concatenate([a[np.newaxis, :, :]]*n).shape Out[285]: (10, 3, 4, 4) 

Actuación:

 # ~ 4x faster than using `np.stack` In [292]: %timeit np.concatenate([a[np.newaxis, :, :]]*n) 100000 loops, best of 3: 10.7 µs per loop In [293]: %timeit np.stack([a]*n) 10000 loops, best of 3: 41.1 µs per loop 

Enfoque # 1: Una forma sería con np.repeat para repetir a lo largo del primer eje después de extender la matriz de entrada para tener una dimensión más, un singleton con None/np.newaxis

 np.repeat(a[None],n,axis=0) 

Ejecuciones de muestra

1) caso 2D:

 In [209]: a Out[209]: array([[7, 8, 0, 1], [5, 0, 1, 0], [4, 3, 0, 1]]) In [210]: np.repeat(a[None],2,axis=0) Out[210]: array([[[7, 8, 0, 1], [5, 0, 1, 0], [4, 3, 0, 1]], [[7, 8, 0, 1], [5, 0, 1, 0], [4, 3, 0, 1]]]) 

2) caso 3D:

 In [214]: a Out[214]: array([[[7, 2, 4, 2], [6, 7, 7, 6], [6, 8, 2, 1]], [[1, 5, 8, 5], [8, 0, 6, 4], [1, 2, 8, 8]]]) In [215]: np.repeat(a[None],2,axis=0) Out[215]: array([[[[7, 2, 4, 2], [6, 7, 7, 6], [6, 8, 2, 1]], [[1, 5, 8, 5], [8, 0, 6, 4], [1, 2, 8, 8]]], [[[7, 2, 4, 2], [6, 7, 7, 6], [6, 8, 2, 1]], [[1, 5, 8, 5], [8, 0, 6, 4], [1, 2, 8, 8]]]]) 

Enfoque # 2: Si no le importa una versión de solo lectura de la matriz de entrada, podríamos usar np.broadcast_to

 np.broadcast_to(a, (n,) + a.shape) 

Enfoque n. ° 3: si no le importa una vista en la matriz de entrada, aquí hay una con pasos NumPy:

 def strided_repeat_newaxis0(a, n): s0,s1,s2 = a.strides shp = (n,) + a.shape return np.lib.index_tricks.as_strided(a, shape=shp, strides=(0,s0,s1,s2)) 

Prueba de tiempo de ejecución

 In [290]: a = np.random.randint(0,9,(3,128,192)) In [291]: %timeit np.repeat(a[None],100,axis=0) 100 loops, best of 3: 6.15 ms per loop In [292]: %timeit strided_repeat_newaxis0(a, 100) 100000 loops, best of 3: 4.69 µs per loop In [293]: %timeit np.broadcast_to(a, (n,) + a.shape) 100000 loops, best of 3: 3.03 µs per loop