I have a list of 3D arrays that are all different shapes, but I need them to all be the same shape. Also, that shape needs to be the smallest shape in the list.
For example my_list with three arrays have the shapes (115,115,3), (111,111,3), and (113,113,3) then they all need to be (111,111,3). They are all square color images so they will be of shape (x,x,3).
So I have two main problems:
for idx, img in enumerate(my_list):
img = img[:smallest_shape,:smallest_shape]
my_list[idx] = img
I constructed a sample list with
In : alist=[np.ones((512,512,3)) for _ in range(100)]
and did some timings.
Collecting shapes is fast:
In : timeit [a.shape for a in alist] 10000 loops, best of 3: 31.2 µs per loop
Taking the min takes more time:
In : np.min([a.shape for a in alist],axis=0) Out: array([512, 512, 3]) In : timeit np.min([a.shape for a in alist],axis=0) 1000 loops, best of 3: 344 µs per loop
slicing is faster
In : timeit [a[:500,:500,:] for a in alist] 10000 loops, best of 3: 133 µs per loop
now try to isolate the
In : shapes=[a.shape for a in alist] In : timeit np.min(shapes, axis=0) The slowest run took 5.75 times longer than the fastest. This could mean that an intermediate result is being cached. 10000 loops, best of 3: 136 µs per loop
When you have lists of objects, iteration is the only way to deal with all elements. Look at the code for
np.vstack (and others). They do one or more list comprehensions to massage all the input arrays into the correct shape. Then they do
np.concatenate which iterates too, but in compiled code.