python python-2.7 numpy numpy-broadcasting

python - Numpy: crea una matriz con filas de vectores



python-2.7 numpy-broadcasting (1)

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 una manera inteligente, utilizando la transmisión, pero solo puedo pensar en hacerlo con un bucle for.


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

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

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

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

Ejecución de 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, 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 réplicas, de esta manera:

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 , simplemente puede crear una vista 2D en el vector entrada y, como tal, esto sería prácticamente libre 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 rápida de tiempo de ejecución que compara los diversos 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