Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy - create matrix with rows of vector

Tags:

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.

like image 213
fulaphex Avatar asked Oct 18 '15 16:10

fulaphex


People also ask

How do I add a row to a numpy matrix?

Use the numpy. append() Function to Add a Row to a Matrix in NumPy. The append() function from the numpy module can add elements to the end of the array. By specifying the axis as 0, we can use this function to add rows to a matrix.

How do you make a 3x3 matrix in Python?

You can use numpy. First, convert your list into numpy array. Then, take an element and reshape it to 3x3 matrix.


1 Answers

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
like image 171
Divakar Avatar answered Oct 19 '22 07:10

Divakar