Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list of 2D numpy arrays to one 3D numpy array?

Tags:

python

numpy

I have a list of several hundred 10x10 arrays that I want to stack together into a single Nx10x10 array. At first I tried a simple

newarray = np.array(mylist)

But that returned with "ValueError: setting an array element with a sequence."

Then I found the online documentation for dstack(), which looked perfect: "...This is a simple way to stack 2D arrays (images) into a single 3D array for processing." Which is exactly what I'm trying to do. However,

newarray = np.dstack(mylist)

tells me "ValueError: array dimensions must agree except for d_0", which is odd because all my arrays are 10x10. I thought maybe the problem was that dstack() expects a tuple instead of a list, but

newarray = np.dstack(tuple(mylist))

produced the same result.

At this point I've spent about two hours searching here and elsewhere to find out what I'm doing wrong and/or how to go about this correctly. I've even tried converting my list of arrays into a list of lists of lists and then back into a 3D array, but that didn't work either (I ended up with lists of lists of arrays, followed by the "setting array element as sequence" error again).

Any help would be appreciated.

like image 284
James Avatar asked Dec 03 '10 00:12

James


People also ask

How do you make a 3d NumPy array?

A three dimensional means we can use nested levels of array for each dimension. To create a 3-dimensional numpy array we can use simple numpy. array() function to display the 3-d array.


1 Answers

newarray = np.dstack(mylist)

should work. For example:

import numpy as np

# Here is a list of five 10x10 arrays:
x = [np.random.random((10,10)) for _ in range(5)]

y = np.dstack(x)
print(y.shape)
# (10, 10, 5)

# To get the shape to be Nx10x10, you could  use rollaxis:
y = np.rollaxis(y,-1)
print(y.shape)
# (5, 10, 10)

np.dstack returns a new array. Thus, using np.dstack requires as much additional memory as the input arrays. If you are tight on memory, an alternative to np.dstack which requires less memory is to allocate space for the final array first, and then pour the input arrays into it one at a time. For example, if you had 58 arrays of shape (159459, 2380), then you could use

y = np.empty((159459, 2380, 58))
for i in range(58):
    # instantiate the input arrays one at a time
    x = np.random.random((159459, 2380))
    # copy x into y
    y[..., i] = x
like image 96
unutbu Avatar answered Oct 13 '22 17:10

unutbu