Numpy – crea una matriz con filas de vectores

Tengo un vector [x,y,z,q] y quiero crear una matriz:

 [[x,y,z,q], [x,y,z,q], [x,y,z,q], ... [x,y,z,q]] 

con m filas. Creo que esto podría hacerse de alguna manera inteligente, utilizando la transmisión, pero solo puedo pensar en hacerlo con un bucle for.

Ciertamente es posible con la broadcasting después de agregar con m ceros a lo largo de las columnas, como así:

 np.zeros((m,1),dtype=vector.dtype) + vector 

Ahora, NumPy ya tiene una función incorporada np.tile para exactamente la misma tarea:

 np.tile(vector,(m,1)) 

Ejecución de la muestra

 In [496]: vector Out[496]: array([4, 5, 8, 2]) In [497]: m = 5 In [498]: np.zeros((m,1),dtype=vector.dtype) + vector Out[498]: array([[4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2]]) In [499]: np.tile(vector,(m,1)) Out[499]: array([[4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2]]) 

También puede usar np.repeat después de extender su dimensión con np.newaxis/None para el mismo efecto, como así:

 In [510]: np.repeat(vector[None],m,axis=0) Out[510]: array([[4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2]]) 

También puede usar integer array indexing para obtener las replicaciones, como así:

 In [525]: vector[None][np.zeros(m,dtype=int)] Out[525]: array([[4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2]]) 

Y finalmente, con np.broadcast_to , puede simplemente crear una vista 2D en el vector entrada y, como tal, esto sería prácticamente gratis y sin necesidad de memoria adicional. Entonces, simplemente haríamos –

 In [22]: np.broadcast_to(vector,(m,len(vector))) Out[22]: array([[4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2], [4, 5, 8, 2]]) 

Prueba de tiempo de ejecución –

Aquí hay una prueba de tiempo de ejecución rápida que compara los distintos enfoques:

 In [12]: vector = np.random.rand(10000) In [13]: m = 10000 In [14]: %timeit np.broadcast_to(vector,(m,len(vector))) 100000 loops, best of 3: 3.4 µs per loop # virtually free! In [15]: %timeit np.zeros((m,1),dtype=vector.dtype) + vector 10 loops, best of 3: 95.1 ms per loop In [16]: %timeit np.tile(vector,(m,1)) 10 loops, best of 3: 89.7 ms per loop In [17]: %timeit np.repeat(vector[None],m,axis=0) 10 loops, best of 3: 86.2 ms per loop In [18]: %timeit vector[None][np.zeros(m,dtype=int)] 10 loops, best of 3: 89.8 ms per loop