23

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.

1 Answer 1

31

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.