I have a vector [x,y,z,q] and I want to create a matrix:
[[x,y,z,q], [x,y,z,q], [x,y,z,q], ... [x,y,z,q]]
with m rows. I think this could be done in some smart way, using broadcasting, but I can only think of doing it with a for loop.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Certainly possible with broadcasting after adding with m zeros along the columns, like so –
np.zeros((m,1),dtype=vector.dtype) + vector
Now, NumPy already has an in-built function np.tile for exactly that same task –
np.tile(vector,(m,1))
Sample run –
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]])
You can also use np.repeat after extending its dimension with np.newaxis/None for the same effect, like so –
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]])
You can also use integer array indexing to get the replications, like so –
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]])
And finally with np.broadcast_to, you can simply create a 2D view into the input vector and as such this would be virtually free and with no extra memory requirement. So, we would simply do –
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]])
Runtime test –
Here’s a quick runtime test comparing the various approaches –
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0