1

Given a list with 6 2D arrays with the same dimension (200, 200). Every three consecutive arrays can be stacked up to a 3D array.

Desired output:

array = (200, 200, 3, 2)

I am familiar with np.dstack:

n = 6
array = []
for i in range(n):
    x = np.random.randn(n1, n2)
    array.append(x)
array = np.dstack(array)

Speed should be considered as I am working with large data sets.


Edit: I created images for testing: https://wetransfer.com/downloads/afb0a2fbfbd8b6047a68dad41b56a0d520200509184625/761355

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Adapted Paddy's answer:

import numpy as np
from skimage import io
import glob
from natsort import natsorted

DIR = (Set folder path with the test images)

list_path = glob.glob(DIR + "/*.png")
list_path_sorted = natsorted(list_path)
array = []
for i in range(len(list_path_sorted)):
    image = np.array( io.imread(list_path_sorted[i]) )
    array.append(image)
a = np.dstack(array).reshape(200, 200, 3, 2)

a.shape
>>> (200, 200, 3, 2)

Issue: The order in the third dimension doesn't match. To test this:

plt.imshow(a[:,:,0,0]) -> should show picture with A1
plt.imshow(a[:,:,2,0]) -> should show picture with A3
plt.imshow(a[:,:,0,1]) -> should show picture with B1
plt.imshow(a[:,:,2,1]) -> should show picture with B3
2
  • 3
    And question is? Commented May 9, 2020 at 17:33
  • I stuck with the condition that three consecutive arrays in a list forms a 3D stack. Commented May 9, 2020 at 17:37

2 Answers 2

2

dstack as you suggested then reshape the resulting array:

import numpy as np

# six arrays of (200, 200)
n = 6
array = []
for i in range(n):
    x = np.random.randn(n1, n2)
    array.append(x)

# EDIT to use 'F' ordering
a = np.dstack(array).reshape(200, 200, 3, 2, order='F')

a.shape
>>> (200, 200, 3, 2)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the quick answer. It seems the order of the arrays are not correct. I replaced the line: x = np.random.randn(n1, n2) with random test images to test this.
Made an edit to fix the problem. Normally uses 'C' (row) ordering, but it can also use 'F' (column, F for Fortran) ordering. In this case the images should be in the correct place, ie. a[:,:,0,0] = 'A1', a[:,:,0,1] = 'B1' (whereas before a[:,:,0,1] = 'A2').
1

I can't play with your images, so I'll generate a list of distinctive (2,2) arrays:

In [412]: alist = [np.arange(i,i+4).reshape(2,2) for i in range(6)]                                    
In [413]: alist                                                                                        
Out[413]: 
[array([[0, 1],
        [2, 3]]), array([[1, 2],
        [3, 4]]), array([[2, 3],
        [4, 5]]), array([[3, 4],
        [5, 6]]), array([[4, 5],
        [6, 7]]), array([[5, 6],
        [7, 8]])]

With dstack we get a (2,2,6) array

In [414]: arr = np.dstack(alist)                                                                       
In [415]: arr                                                                                          
Out[415]: 
array([[[0, 1, 2, 3, 4, 5],
        [1, 2, 3, 4, 5, 6]],

       [[2, 3, 4, 5, 6, 7],
        [3, 4, 5, 6, 7, 8]]])

The (3,2) reshape produces:

In [417]: arr.reshape(2,2,3,2)                                                                         
Out[417]: 
array([[[[0, 1],
         [2, 3],
         [4, 5]],

        [[1, 2],
         [3, 4],
         [5, 6]]],


       [[[2, 3],
         [4, 5],
         [6, 7]],

        [[3, 4],
         [5, 6],
         [7, 8]]]])

Sounds like you aren't happy with that layout (your edits are bit unclear). We can transpose values

In [419]: arr.reshape(2,2,2,3).transpose(0,1,3,2)                                                      
Out[419]: 
array([[[[0, 3],
         [1, 4],
         [2, 5]],

        [[1, 4],
         [2, 5],
         [3, 6]]],


       [[[2, 5],
         [3, 6],
         [4, 7]],

        [[3, 6],
         [4, 7],
         [5, 8]]]])

With this last arrangement,

In [431]: _419[:,:,2,0]                                                                                
Out[431]: 
array([[2, 3],
       [4, 5]])
In [432]: _413[2]       # alist                                                                               
Out[432]: 
array([[2, 3],
       [4, 5]])

In [435]: _419[:,:,0,1]                                                                                
Out[435]: 
array([[3, 4],
       [5, 6]])
In [436]: _413[3]                                                                                      
Out[436]: 
array([[3, 4],
       [5, 6]])

2 Comments

I apologise for the poor edits. Please see the updated edits with a working code and download link to the images. Just set the DIR to the download folder with the images. I hope it makes it clearer.
Assuming your images are in the list in the order [A1,A2,A3,B1,B2,B3], then my last ordering is one you want - see my edit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.