Numpy - create matrix with rows of vector
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
Create a matrix from a vector where each row is a shifted version of the vector
Here's one approach using NumPy strides
basically padding with the leftover elements and then the strides
helping us in creating that shifted version pretty efficiently -
def strided_method(ar):
a = np.concatenate(( ar, ar[:-1] ))
L = len(ar)
n = a.strides[0]
return np.lib.stride_tricks.as_strided(a[L-1:], (L,L), (-n,n))
Sample runs -
In [42]: ar = np.array([1, 2, 3, 4])
In [43]: strided_method(ar)
Out[43]:
array([[4, 1, 2, 3],
[3, 4, 1, 2],
[2, 3, 4, 1],
[1, 2, 3, 4]])
In [44]: ar = np.array([4,9,3,6,1,2])
In [45]: strided_method(ar)
Out[45]:
array([[2, 4, 9, 3, 6, 1],
[1, 2, 4, 9, 3, 6],
[6, 1, 2, 4, 9, 3],
[3, 6, 1, 2, 4, 9],
[9, 3, 6, 1, 2, 4],
[4, 9, 3, 6, 1, 2]])
Runtime test -
In [5]: a = np.random.randint(0,9,(1000))
# @Eric's soln
In [6]: %timeit roll_matrix(a)
100 loops, best of 3: 3.39 ms per loop
# @Warren Weckesser's soln
In [8]: %timeit circulant(a[::-1])
100 loops, best of 3: 2.03 ms per loop
# Strides method
In [18]: %timeit strided_method(a)
100000 loops, best of 3: 6.7 µs per loop
Making a copy (if you want to make changes and not just use as a read only array) won't hurt us too badly for the strides
method -
In [19]: %timeit strided_method(a).copy()
1000 loops, best of 3: 381 µs per loop
Adding a vector to matrix rows in numpy
For adding a 1d array to every row, broadcasting already takes care of things for you:
mat += vec
However more generally you can use np.newaxis
to coerce the array into a broadcastable form. For example:
mat + np.ones(3)[np.newaxis,:]
While not necessary for adding the array to every row, this is necessary to do the same for column-wise addition:
mat + np.ones(5)[:,np.newaxis]
EDIT: as Sebastian mentions, for row addition, mat + vec
already handles the broadcasting correctly. It is also faster than using np.newaxis
. I've edited my original answer to make this clear.
How to concatenate a vector into rows of a numpy matrix?
output = np.zeros((2,4), int)
output[:, :2] = a # broadcasts (2,) to (1,2) to (2,2)
output[:, 2:] = b
How to build a numpy array row by row in a for loop?
A numpy array must be created with a fixed size. You can create a small one (e.g., one row) and then append rows one at a time, but that will be inefficient. There is no way to efficiently grow a numpy array gradually to an undetermined size. You need to decide ahead of time what size you want it to be, or accept that your code will be inefficient. Depending on the format of your data, you can possibly use something like numpy.loadtxt
or various functions in pandas to read it in.
Python Numpy: Adding vector to existing matrix row
In [74]: A = np.arange(1,10).reshape(3,3); v = np.arange(1,4)
In [75]: A
Out[75]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [77]: v
Out[77]: array([1, 2, 3])
Expand A
to a (3,3,3):
In [78]: A[None,:,:].repeat(3,0)
Out[78]:
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
Do the same with v
:
In [79]: np.eye(3)
Out[79]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
In [80]: np.eye(3)[:,:,None]*v
Out[80]:
array([[[1., 2., 3.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[1., 2., 3.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[1., 2., 3.]]])
add the two:
In [81]: _78+_80
Out[81]:
array([[[ 2., 4., 6.],
[ 4., 5., 6.],
[ 7., 8., 9.]],
[[ 1., 2., 3.],
[ 5., 7., 9.],
[ 7., 8., 9.]],
[[ 1., 2., 3.],
[ 4., 5., 6.],
[ 8., 10., 12.]]])
or in one step:
A+np.eye(3)[:,:,None]*v
How to combine column vectors into a matrix
Here you have equivalent complete examples in Matlab and Python/NumPy:
% Matlab
f = 0.1;
time = [0; 1; 2; 3];
D0 = [cos(2*pi*f*time), sin(2*pi*f*time), repmat(1,length(time),1)]
# Python
import numpy as np
f = 0.1
time = np.array([0, 1, 2, 3])
D0 = np.array([np.cos(2*np.pi*f*time), np.sin(2*np.pi*f*time), np.ones(time.size)]).T
print(D0)
Note that unlike Matlab, Python/NumPy has no special syntax to distinguish rows from columns (,
vs. ;
in Matlab). Similarly, a 1D NumPy array has no notion of either being a "column" or "row" vector. When merging several 1D NumPy arrays into a single 2D array, as above, each 1D array ends up as a row in the 2D array. As you want them as columns, you need to transpose the 2D array, here accomplished simply by the .T
attribute.
Related Topics
Python's JSON Module, Converts Int Dictionary Keys to Strings
Why Does My Pandas Dataframe Not Display New Order Using 'Sort_Values'
What Is the _Dict_._Dict_ Attribute of a Python Class
How to Automatically Fix an Invalid JSON String
How to Set the Absolute Position of Figure Windows with Matplotlib
Imports in _Init_.Py and 'Import As' Statement
How to Improve the Label Placement in Scatter Plot
How Does the Key Argument in Python's Sorted Function Work
Getting the Caller Function Name Inside Another Function in Python
Cannot Return Results from Stored Procedure Using Python Cursor
How to Change a Module Variable from Another Module
Classification Using Movie Review Corpus in Nltk/Python
Add Column to Dataframe with Constant Value
How to Check If One Two-Dimensional Numpy Array Contains a Specific Pattern of Values Inside It
Nested Dictionary to Multiindex Dataframe Where Dictionary Keys Are Column Labels
Difference Between "Findall" and "Find_All" in Beautifulsoup