Numpy append multiple arrays - python

In R it is very easy to combine multiple vectors, for instance:
a<-c(1,2,3)
b<-c(4,5,6,7)
c<-c(8,9,10)
#combine to
d<-c(a,b,c)
This is what I want to recreate by using NumPy.
I tried to achieve this using np.append, and it works fine as long as all arrays have the same length, for instance:
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.array([7,8,9])
d = np.append(a,(b,c)) #works fine
However
a = np.array([1,2,3])
b = np.array([4,5,6,7])
c = np.array([8,9,10])
d = np.append(a,(b,c)) #does not work fine
The result is: [1,2 3 array([4,5,6,7]) array([8,9,10])]. How do I turn this into a classic NumPy array [1 2 3 4 5 6 7 8 9 10]?

I think you need this function:
np.concatenate([a,b,c])
am I right?
np.concatenate is used to concatenate arrays with same number of dimension, but different size, along one specific axis (0 axis by default). In your case, since you have just one dimension and you want to concatenate on the unique dimension you have, you can also use np.hstack([a,b,c]), as mentioned by #Sembei Norimaki in the comments.
EDIT to answer you question in the comments:
in the source code of numpy:
if axis is None:
if arr.ndim != 1:
arr = arr.ravel()
values = ravel(values)
axis = arr.ndim-1
return concatenate((arr, values), axis=axis)
as you can see, the values to append are forced to be a numpy array before appending them (this happens in the ravel function). Since your arrays have different shape, it is not possible to cast them in an integers numpy array and so a numpy array of numpy arrays is created (try np.array((b,c)) and see what happens). For this reason your are appending a numpy array of numpy arrays to an integer numpy array and this causes the problem.

Related

How to gather arrays of different sizes in the same array with Numpy?

Context: I have 3 arrays. A that is 3x3, B that is 5x2, and C that is a 3D array.
Question: Is there a way to stack arrays of different sizes along the 1st dimension of a 3D array, with Numpy ?
Example: if A and B are stacked in C along its first dimension, and I want to access A, I would type C[0].
Problem: I know I can use Xarray for that, but I wanted to know if there was a Numpy way to do it. So far, I have been artificially extending the arrays with NaNs to match their sizes (see code below).
Code:
# Generate the arrays
A = np.random.rand(3,3)
B = np.random.rand(5,2)
C = np.zeros((2,5,3))
# Resize the arrays to fit C
AR = np.full([C.shape[1], C.shape[2]], np.nan) # Generate an array full of NaNs that fits C
AR[:A.shape[0],:A.shape[1]] = A # Input the previous array in the resized one
BR = np.full([C.shape[1], C.shape[2]], np.nan) # Generate an array full of NaNs that fits C
BR[:B.shape[0],:B.shape[1]] = B # Input the previous array in the resized one
# Stack the resized arrays in C
C[0] = AR
C[1] = BR
You won't be able to slice it as freely, but you can use dtype = 'object' when making a jagged array.
jagged_array = np.array([np.zeros((3, 2)), np.zeros((5, 2)), np.zeros((3, 2, 5))], dtype = 'object')

How can I put two NumPy arrays into a matrix with two columns?

I am trying to put two NumPy arrays into a matrix or horizontally stack them. Each array is 76 elements long, and I want the ending matrix to have 76 rows and 2 columns. I basically have a velocity/frequency model and want to have two columns with corresponding frequency/velocity values in each row.
Here is my code ('f' is frequency and 'v' the velocity values, previously already defined):
print(f.shape)
print(v.shape)
print(type(f))
print(type(v))
x = np.concatenate((f, v), axis = 1)
This returns
(76,)
(76,)
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
And an error about the concatenate line that says:
AxisError: axis 1 is out of bounds for array of dimension 1
I've also tried hstack except for concatenate, as well as vstack and transposing .T, and have the same error. I've also tried using Pandas, but I need to use NumPy, because when I save it into a txt/dat file, Pandas gives me an extra column with numbering that I do not need to have.
Your problem is that your vectors are one-dimensional, like in this example:
f_1d = np.array([1,2,3,4])
print(f_1d.shape)
> (4,)
As you can see, only the first dimension is given. So instead you could create your vectors like this:
f = np.expand_dims(np.array([1,2,3,4]), axis=1)
v = np.expand_dims(np.array([5,6,7,8]), axis=1)
print(f.shape)
print(v.shape)
>(4,1)
>(4,1)
As you may notice, the second dimension is equal to one, but now your vector is represented in matrix form.
It is now possible to transpose the matrix-vectors:
f_t = f.T
v_t = v.T
print(f_t)
> (1,4)
Instead of using concatenate, you could use vstack or hstack to create cleaner code:
x = np.hstack((f,v))
x_t = np.vstack((f_t,v_t))
print(x.shape)
print(x_t.shape)
>(4,2)
>(2,4)

add column Numpy array python

I am very new to python and am very familiar with R, but my question is very simple using Numpy Arrays:
Observe:
I have one array X of dimension (100,2) of floating point type and I want to add a 3rd column, preferably into a new Numpy array of dimension (100,3) such that the 3rd column = col(1)^2 for every row in array of X.
My understanding is Numpy arrays are generally of fixed dimension so I'm OK with creating a new array of dim 100x3, I just don't know how to do so using Numpy arrays.
Thanks!
One way to do this is by creating a new array and then concatenating it. For instance, say that M is currently your array.
You can compute col(1)^2 as C = M[:,0] ** 2 (which I'm interpreting as column 1 squared, not column 1 to the power of the values in column two). C will now be an array with shape (100, ), so we can reshape it using C = np.expand_dims(C, 1) which will create a new axis of length 1, so our new column now has shape (100, 1). This is important because we want all both of our arrays to have the same number of dimensions when concatenating them.
The last step here is to concatenate them using np.concatenate. In total, our result looks like this
C = M[:, 0] ** 2
C = np.expand_dims(C, 1)
M = np.concatenate([M, C], axis=1) #third row will now be col(1) ^ 2
If you're the kind of person who likes to do things in one line, you have:
M = np.concatenate([M, np.expand_dims(M[:, 0] ** 2, 0)], axis=1)
That being said, I would recommend looking at Pandas, it supports these actions more naturally, in my opinion. In Pandas, it would be
M["your_col_3_name"] = M["your_col_1_name"] ** 2
where M is a pandas dataframe.
Append with axis=1 should work.
a = np.zeros((5,2))
b = np.ones((5,1))
print(np.append(a,b,axis=1))
This should return:
[[0,0,1],
[0,0,1],
[0,0,1],
[0,0,1],
[0,0,1]]
# generate an array with shape (100,2), fill with 2.
a = np.full((100,2),2)
# calcuate the square to first column, this will be a 1-d array.
squared=a[:,0]**2
# concatenate the 1-d array to a,
# first need to convert it to 2-d arry with shape (100,1) by reshape(-1,1)
c = np.concatenate((a,squared.reshape(-1,1)),axis=1)

Are the dimensions of arrays max 2 that be created with np.arange?

I'm new in NumPy. While i was reading the NumPy User Guide and making examples , i saw an example that made me to ask a question.
For example Python gave the below results:
>>> import numpy as np
>>> a = np.arange(6)
>>> a.ndim
1
>>> b = np.arange(6).reshape(2,3)
>>> b.ndim
2
>>> c = np.arange(6).reshape(3,2)
>>> c.ndim
2
I expected that c.ndim would given 3 rather than 2. So my question is, are the max dimension sizes of arrays are 2 when these arrays are created with np.arange() function?
What you are actually doing is first creating a 1D array with arange then reshape it.
a = np.arange(20) # of dimension 1
a = a.reshape(4,5)
print(a.ndim) # returns 2 because the array became a 2D 4x5
a = a.reshape(2,5,2)
print(a.ndim) # returns 3 because the array becomes a 3D 2x5x2
to summarize, you are forcing a reshape of a 1D np.array to a 2D using the reshape method, add more arguments to access more dimensions.

subtract rows one by one from numpy array

I have a 2D numpy array, A.
I want to subtract each rows, one by one, from A, and store the row-wise absolute sum in an array.
Is there a way to carry out the operation without using the for loop ? Below is the code with for loop.
import numpy as np
A = np.random.randint(5,size=(8,9))
b = np.zeros(A.shape[1]);
for i in xrange(A.shape[0]):
b = b + np.sum(np.absolute(A - A[i,:]), axis=0)
You could use broadcasting -
(np.abs(A[:,None,:] - A)).sum(axis=(0,1))
Steps :
(1) Keeping the last axis aligned get two versions of A :
Input1 (A[:,None,:]) : M x 1 x N
Input2 (A) : M x N
Get the absolution differences between these two inputs resulting in a 3D array.
(2) Sum along the first two axes for final output.

Categories

Resources