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

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

Related

How to reshape in Python by preserving structure of matrix

I am trying to make a transformation that I thought to be trivial but I am not able to find any solution to this. I have an array of dimensions (3, 3, 2), such as the following one:
array([[1,2], [3,4], [5,6]],
[[7,8], [9,0], [1,2]],
[[3,4], [5,6], [7,8]])
I would like to transform it to a (2, 3, 3) array of the following form
array([[1, 3, 5],
[7, 9, 1],
[3, 5, 7]],
[[2, 4, 6],
[8, 0, 2],
[4, 6, 8]])
such that each matrix of this array contains all the elements of the respective indices for each tuple in the first matrix. Is there any way to do this, either with NumPy or preprocessing tools of ML libraries? In a sense this operation corresponds to "decoupling" the channels of an image in two separate matrix.
As suggested by user hpaulj, the operations needed to do this were np.swapaxes(A, 0, 2).transpose(0,2,1) if A was the original array.
As explained in the documentation, swapaxes interchanges the two axes of a multidimensional array. This leaves the submatrices in a transposed form with respect to the one we want, so we should transpose the array in such a way to preserve the order of the array containing the submatrices and transposing only the submatrices themselves.

Transforming a 2D array to 1D array to create Data Frame

I have three 2D np.array that mathematically are [8:1550] matrices, and I want to express them into 1D np.array of 12400 numbers (8 x 1550 = 12400...) so that I could create a DataFrame later with this code:
Exported_Data = pd.DataFrame({"UD": UD_Data, "NS": NS_Data, "EW": EW_Data})
Exported_Data.to_csv("EXCEL.csv")
To put a simpler example, if I have this:
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
And I want to obtain this from that:
B = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
What is the best way to do it?
I would suggest use reshape. It most likely creates a view and is more efficient whereas np.flatten creates a copy:
B = A.reshape(-1)
-1 implicitly takes care of required dimension size.
You can use A.flatten() to convert a 2D array to a 1D array.

Multiplication of two matrices of different size numpy

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)

Vectorize np.arange or equivalent

I have a long 1D array. I'd like to create an array that is the result of np.arange() applied to each value in the array plus some constant. E.g if the constant = 3 and my array looks like
[1,2,3,4,5]
I'd like to get
[[1,2,3]
[2,3,4]
[3,4,5]
[4,5,6]
[5,6,7]]
np.arange() only accepts scalars as arguments. I played around with np.vectorize() a bit to no success. Clearly I could do this with a loop, or with lists and then convert to an array, but I was wondering if there's a good numpy-only solution.
You could use addition and broadcasting:
>>> x = np.array([1,2,3,4,5])
>>> constant = 3
>>> x[:,None] + np.arange(constant)
array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6],
[5, 6, 7]])
This could also be written as np.add.outer(x, np.arange(constant)).

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