Multiplication of two matrices of different size numpy - python

I want to multiply two matrices :
a = np.array([[1,2],[3,4]])
b = np.array([[2,3,4],[5,6,7]])
a
array([[1, 2],
[3, 4]])
b
array([[2, 3, 4],
[5, 6, 7]])
I want result something like:
array([[2,4,3,6,4,8],[15,20,18,24,21,28]])
How can I do it using numpy?
Need help.
Thanks in advance.

Answered here.
You can use numpy broadcasting or use the outer product.
a[:,:,None]*b
or
np.outer(a,b)

Related

Efficient row elements multiplication in numpy

Is there any efficient way to find the multiplication of every row in a matrix using numpy?
I mean, for example, if
A = [[1, 2], [3, 4]]
then I would want something like np.sum(A, axis=1) just,
np.mul(A, axis=0) = [2, 12]
np.prod is what you're looking for.
a = np.array([[1, 2], [3, 4]])
print(np.prod(a, axis=1)) # Prints array([2, 12])
Use nympy.prod, exactly as you describe, i.e.
import numpy as np
A = [[1, 2], [3, 4]]
np.prod(A, axis=1) # Gives [ 2 12]
The multiply function is an universal function (ufunc) so you could do:
import numpy as np
A = np.array([[1, 2], [3, 4]])
result = np.multiply.reduce(A, axis=1)
print(result)
Output
[ 2 12]
Read the documentation on reduce, here.

Combinations between two arrays numpy different shapes

I know it is possible to use meshgrid to get all combinations between two arrays using numpy.
But in my case I have an array of two columns and n rows and another array that I would like to get the unique combinations.
For example:
a = [[1,1],
[2,2],
[3,3]]
b = [5,6]
# The expected result would be:
final_array = [[1,1,5],
[1,1,6],
[2,2,5],
[2,2,6],
[3,3,5],
[3,3,6]]
Which method is the fastest way to get this result using only numpy?
Proposed solution
Ok got the result, but I would like to know if this is a reliable and fast solution for this task, if someone could give me any advice I will appreciate.
a_t = np.tile(a, len(b)).reshape(-1,2)
b_t = np.tile(b, len(a)).reshape(1,-1)
final_array = np.hstack((a_t,b_t.T))
array([[1, 1, 5],
[1, 1, 6],
[2, 2, 5],
[2, 2, 6],
[3, 3, 5],
[3, 3, 6]])
Kind of ugly, but here's one way:
xx = np.repeat(a, len(b)).reshape(-1, a.shape[1])
yy = np.tile(b, a.shape[0])[:, None]
np.concatenate((xx, yy), axis=1)

Python: Concatenate all combinations of numpy array rows

In python need to combine two 2-dimensional numpy arrays, so that the resulting rows are combinations of the rows from the input arrays concatenated together. I need the fastest solution so it can be used in arrays that are very big.
For example:
I got:
import numpy as np
array1 = np.array([[1,2],[3,4]])
array2 = np.array([[5,6],[7,8]])
I want the code to return:
[[1,2,5,6]
[1,2,7,8]
[3,4,5,6]
[3,4,7,8]]
Solution using numpy's repeat, tile and hstack
The snippet
result = np.hstack([
np.repeat(array1, array2.shape[0], axis=0),
np.tile(array2, (array1.shape[0], 1))
])
Step by step explanation
We start with the two arrays, array1 and array2:
import numpy as np
array1 = np.array([[1,2],[3,4]])
array2 = np.array([[5,6],[7,8]])
First, we duplicate the content of array1 using repeat:
a = np.repeat(array1, array2.shape[0], axis=0)
The content of a is:
array([[1, 2],
[1, 2],
[3, 4],
[3, 4]])
Then we repeat the second array, array2, using tile. In particular, (array1.shape[0],1) replicates array2 in the first direction array1.shape[0] times and just 1 time in the other direction.
b = np.tile(array2, (array1.shape[0],1))
The result is:
array([[5, 6],
[7, 8],
[5, 6],
[7, 8]])
Now we can just proceed to stack the two results, using hstack:
result = np.hstack([a,b])
Achieving the desired output:
array([[1, 2, 5, 6],
[1, 2, 7, 8],
[3, 4, 5, 6],
[3, 4, 7, 8]])
For this small example, itertools.product is actually faster. I don't know how it scales
alist = list(itertools.product(array1.tolist(),array2.tolist()))
np.array(alist).reshape(-1,4)

How to sum 2d and 1d arrays in numpy?

Supposing I have 2d and 1d numpy array. I want to add the second array to each subarray of the first one and to get a new 2d array as the result.
>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> b = np.array([2, 3])
>>> c = ... # <-- What should be here?
>>> c
array([[3, 5],
[5, 7],
[7, 9],
[9, 22]])
I could use a loop but I think there're standard ways to do it within numpy.
What is the best and quickest way to do it? Performance matters.
Thanks.
I think the comments are missing the explanation of why a+b works. It's called broadcasting
Basically if you have a NxM matrix and a Nx1 vector, you can directly use the + operator to "add the vector to each row of the matrix.
This also works if you have a 1xM vector and want to add it columnwise.
Broadcasting also works with other operators and other Matrix dimensions.
Take a look at the documentation to fully understand broadcasting

Concatenate two NumPy arrays vertically

I tried the following:
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> np.concatenate((a,b), axis=0)
array([1, 2, 3, 4, 5, 6])
>>> np.concatenate((a,b), axis=1)
array([1, 2, 3, 4, 5, 6])
However, I'd expect at least that one result looks like this
array([[1, 2, 3],
[4, 5, 6]])
Why is it not concatenated vertically?
Because both a and b have only one axis, as their shape is (3), and the axis parameter specifically refers to the axis of the elements to concatenate.
this example should clarify what concatenate is doing with axis. Take two vectors with two axis, with shape (2,3):
a = np.array([[1,5,9], [2,6,10]])
b = np.array([[3,7,11], [4,8,12]])
concatenates along the 1st axis (rows of the 1st, then rows of the 2nd):
np.concatenate((a,b), axis=0)
array([[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11],
[ 4, 8, 12]])
concatenates along the 2nd axis (columns of the 1st, then columns of the 2nd):
np.concatenate((a, b), axis=1)
array([[ 1, 5, 9, 3, 7, 11],
[ 2, 6, 10, 4, 8, 12]])
to obtain the output you presented, you can use vstack
a = np.array([1,2,3])
b = np.array([4,5,6])
np.vstack((a, b))
array([[1, 2, 3],
[4, 5, 6]])
You can still do it with concatenate, but you need to reshape them first:
np.concatenate((a.reshape(1,3), b.reshape(1,3)))
array([[1, 2, 3],
[4, 5, 6]])
Finally, as proposed in the comments, one way to reshape them is to use newaxis:
np.concatenate((a[np.newaxis,:], b[np.newaxis,:]))
If the actual problem at hand is to concatenate two 1-D arrays vertically, and we are not fixated on using concatenate to perform this operation, I would suggest the use of np.column_stack:
In []: a = np.array([1,2,3])
In []: b = np.array([4,5,6])
In []: np.column_stack((a, b))
array([[1, 4],
[2, 5],
[3, 6]])
A not well known feature of numpy is to use r_. This is a simple way to build up arrays quickly:
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.r_[a[None,:],b[None,:]]
print(c)
#[[1 2 3]
# [4 5 6]]
The purpose of a[None,:] is to add an axis to array a.
a = np.array([1,2,3])
b = np.array([4,5,6])
np.array((a,b))
works just as well as
np.array([[1,2,3], [4,5,6]])
Regardless of whether it is a list of lists or a list of 1d arrays, np.array tries to create a 2d array.
But it's also a good idea to understand how np.concatenate and its family of stack functions work. In this context concatenate needs a list of 2d arrays (or any anything that np.array will turn into a 2d array) as inputs.
np.vstack first loops though the inputs making sure they are at least 2d, then does concatenate. Functionally it's the same as expanding the dimensions of the arrays yourself.
np.stack is a new function that joins the arrays on a new dimension. Default behaves just like np.array.
Look at the code for these functions. If written in Python you can learn quite a bit. For vstack:
return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
Suppose you have 3 NumPy arrays (A, B, C). You can contact these arrays vertically like this:
import numpy as np
np.concatenate((A, B, C), axis=1)
np.shape

Categories

Resources