Append 2d array to 3d array - python

I have an array of shape (3, 250, 15).
I want to append to it a 2d array of shape (250,15) so that I have a final shape of (4,250,15).
I tried with dstack and np.stack but it does not work.
Can someone give me a suggestion ?

You need to add a dimension (in other words, an axis) to the 2-D array, for example:
import numpy as np
a = np.ones((3, 250, 15))
b = np.ones((250, 15))
c = np.vstack([a, b[None, :, :]])
Now c has shape (4, 250, 15).
If you're not into the None axis trick, you could achieve something similar with np.newaxis or np.reshape.

You can't append a 2D array to a 3D array directly, so you should first expand the axes of the smaller array to become 3D and then append normally. np.expand_dims(b, axis=0) will insert the missing first-axis to array b. Now append the two 3D arrays, np.append(a, b, axis=0).
import numpy as np
a = np.ones((3, 250, 15))
b = np.ones(( 250, 15))
b = np.expand_dims(b, axis=0)
c = np.append(a, b, axis=0)
which works as expected.
print(c.shape)
(4, 250, 15)

Related

"Transform" Numpy Arrray: Move Dimension

I'm creating array a:
import numpy as np
a = np.zeros((3, 10, 10), np.uint8)
a[1,5,5] = 255
with a red dot in the center, where the RGB is the first dimension. Then I plot it using matplotlib:
import matplotlib.pyplot as plt
plt.imshow(a)
But of course this doesn't work because imshow expects an array with dimensions (10, 10, 3) and I am feeding it an array with dimensions (3, 10, 10). How could I 'flip' the array so that the RGB is the third dimension, instead of the first?
What you need is swapaxes.
import numpy as np
a = np.zeros((3, 10, 10), np.uint8)
print(a.shape) #(3,10,10)
print(np.swapaxes(a,0,2).shape) #(10,10,3)
See documentation.
np.swapaxes(a,0,2) equals to np.transpose(a, (2,1,0)).
There is another option which is np.transpose(a, (1,2 0)).
As always, transpose matrix can have two versions which produce similar result but with different 3-dimensional rotational symmetry.
It depends on if the mirror matrix affect your result, you should carefully test if it makes difference.

shape of pandas dataframe to 3d array

I want to convert pandas dataframe to 3d array, but cannot get the real shape of the 3d array:
df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
df['a'][3:]=1
df['a'][:3]=2
a3d = np.array(list(df.groupby('a').apply(pd.DataFrame.as_matrix)))
a3d.shape
(2,)
But, when I set as this, I can get the shape
df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
df['a'][2:]=1
df['a'][:2]=2
a3d = np.array(list(df.groupby('a').apply(pd.DataFrame.as_matrix)))
a3d.shape
(2,2,5)
Is there some thing wrong with the code?
Thanks!
Nothing wrong with the code, it's because in the first case, you don't have a 3d array. By definition of an N-d array (here 3d), first two lines explain that each dimension must have the same size. In the first case:
df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
df['a'][3:]=1
df['a'][:3]=2
a3d = np.array(list(df.groupby('a').apply(pd.DataFrame.as_matrix)))
You have a 1-d array of size 2 (it's what a3d.shape shows you) which contains 2-d array of shape (1,5) and (3,5)
a3d[0].shape
Out[173]: (1, 5)
a3d[1].shape
Out[174]: (3, 5)
so both elements in the first dimension of what you call a3d does not have the same size, and can't be considered as other dimensions of this ndarray.
While in the second case,
df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde'))
df['a'][2:]=1
df['a'][:2]=2
a3d = np.array(list(df.groupby('a').apply(pd.DataFrame.as_matrix)))
a3d[0].shape
Out[176]: (2, 5)
a3d[1].shape
Out[177]: (2, 5)
both elements of your first dimension have the same size, so a3d is a 3-d array.

Numpy group scalars into arrays

I have a numpy array U with shape (20, 50): 20 spatial points, in a space of 50 dimensions.
How can I transform it into a (20, 1, 50) array, i.e. 20 rows, 1 column, and each element is a 50 dimension point? Kind of encapsulating each row as a numpy array.
Context
The point is that I want to expand the array along the columns (actually, replicating the same array along the columns X times) using numpy.concatenate. But if I would do it straight away I would not get the result I want.
E.g., if I would expand it once along the columns, I would get an array with shape (20, 100). But what I would like is to access each element as a 50-dimensional point, so when I expand it I would expect to have a new U' with shape (20, 2, 50).
You can do U[:, None, :] to add a new dimension to the array.
You can also use reshape:
import numpy as np
a = np.zeros((20, 50))
print a.shape # (20, 50)
b = a.reshape((20, 1, 50))
print b.shape # (20, 1, 50)

Removing last 2D array from 3D array

I have a three-dimensional numpy array with shape
(5,5,N)
When I add another 5x5 2D array to this 3D array using numpy.dstack the shape changes like
(5,5,N+1)
and so on. I would like to remove the last 2D array I've added to the stack, such that it goes back to having the shape
(5,5,N)
and possibly (5,5,N-1),(5,5,N-2),...,etc.
What is the most pythonic way to achive this?
I would index as follows:
import numpy as np
a = np.ones((5,5,5))
a.shape
(5, 5, 5)
b = np.ones((5, 5, 5))[:, :, :-1]
b.shape
(5, 5, 4)

How to do dyadics-like operations in numpy

I have two 2-D arrays A and B. I want to get a 3-D array C, whose relation with A and B is:
C_mnl=A_mn*B_ml
How can I do this elegantly in numpy?
numpy.einsum can do that:
a = np.arange(6).reshape(3,2) # a.shape = (3, 2)
b = np.arange(12).reshape(3,4) # b.shape = (3, 4)
c = np.einsum('mn,ml->mnl', a, b) # c.shape = (3, 2, 4)
You can also use broadcasting -
C = A[...,None]*B[:,None,:]
Explanation
A[...,None] adds a new axis as the last axis with None (an equivalent for np.newaxis) pushing all existing dimensions to the front. Thus, this would be same as A[:,:,None].
Similarly with B[:,None,:], it adds a new axis between the existing dimensions.
With steps 1 and 2, we have the axes of the input arrays aligned and thus when operated with elementwise-multiplication would result in the desired output of shape (m,n,l) with broadcasting.

Categories