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