Reshape 3D numpy array with heterogeneous dimensions to 2D numpy array
My data is 3D but only the third axis have a knowed dimension and I need to convert it to a 2D array.
Example:
input =
[[[1, 2, 3]],
[[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]]
input_reshaped =
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
So I have a 3D data in which the first and second dimensions are variable along my dataset and the third one is constant and previous knowed.
Every block in the input are also numpy arrays. I know that I could perform this using numpy.vstack and iterating over first dimension. But I would like to do this reshape in a pythonic way without explicity iterating over my data, if it's possible.
I already tried to perform a list compehension to get the first shape of each block and then sum these values and use it with reshape. Like this:
def myStack(a):
lengths = [item.shape[0] for item in a]
common_dim = a[0].shape[1]
return a.reshape(np.sum(lengths), common_dim)
But with the input in the previous example, I get the following error:
ValueError: cannot reshape array of size 3 into shape (6,3)
Because the Python seen the input has a numy.array with shape (3,)
Any ideas?
Extra: If possible, making a back transformation in the above conditions would be really awesome!
As recommended in the comments, vstack
or concatenate
:
In [320]: alist
Out[320]: [[[1, 2, 3]], [[4, 5, 6], [7, 8, 9]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
In [321]: len(alist)
Out[321]: 3
Trying to make an array from the list just creates a 1d array of lists. Not much help. reshape
won't work.
In [322]: np.array(alist)
Out[322]:
array([list([[1, 2, 3]]), list([[4, 5, 6], [7, 8, 9]]),
list([[1, 2, 3], [4, 5, 6], [7, 8, 9]])], dtype=object)
But concatenate
works with a list of arrays (or array like objects):
In [323]: np.concatenate(alist, axis=0)
Out[323]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
concatenate
will also work with Out[322]
because it treats its input as a list even it is an array.
vstack
is the same thing except it makes sure the subarrays are all 2d, which in this case they already are.