0

If I have a 3D array of ([4,3,3]) like this:

[[0,1,2]   [[9,10,11 ]    [[18,19,20]   [[27,28,29] 
 [3,4,5]    [12,13,14]     [21,22,23]    [30,31,32]
 [6,7,8]] , [15,16,17]] ,  [24,25,26]] , [33,34,35]]

How would I convert it to a 2D array of ([6,6]) like this so that the 1st half of arrays are at the top half of the 160x160 and the 2nd half are at the bottom:

[[0,1,2,9,10,11]
[3,4,5,12,13,14]
[6,7,8,15,16,17]
[18,19,20,27,28,29] 
[21,22,23,30,31,32]
[24,25,26,33,34,35]]

My array creation:

qDCTReversed = np.zeros((400,8,8), dtype=np.int)

And I need a (160,160) array.

7
  • Could you put the code for the creation of the input array? Commented Feb 8, 2019 at 12:42
  • This is just small example but I will add my code below it. Commented Feb 8, 2019 at 12:43
  • 1
    The problem is that the input array do not seem shaped 4, 3,3 Commented Feb 8, 2019 at 12:44
  • is it not? My actual array is 400 arrays of 8x8 arrays Commented Feb 8, 2019 at 12:51
  • 1
    You're data structure is not clear, neither in your comment or in your post. Therefore I'm downvoting it. Commented Feb 8, 2019 at 12:59

3 Answers 3

2

A very fast one line solution using no for-loops is this:

# initialization
qDCTReversed = np.arange(4*3*3).reshape((4,3,3)) 

# calculation
qDCTReversed = qDCTReversed.reshape((2,2,3,3)).transpose((0,2,1,3)).reshape((6,6))

or for the (400,8,8) array:

qDCTReversed.reshape((20,20,8,8)).transpose((0,2,1,3)).reshape((160,160))

Speed comparison:

Mstaino's answer: 0.393 ms

yatu's answer: 0.138 ms

This answer: 0.016 ms

Sign up to request clarification or add additional context in comments.

2 Comments

The problem with this answer is that you are hardcoding everything. The reshapes will have to be modified according to the shape of qDCTReversed
The numbers can easiliy be replaced by calculations from qDCTReversed.shape. The reason I hardcoded it is, so that it's easier to read and understand. I can edit it if wished or needed.
1

You can do this by looping over the list as such:

a = [[[ 0, 1, 2], [ 9,10,11]],
     [[ 3, 4, 5], [12,13,14]],
     [[ 6, 7, 8], [15,16,17]],
     [[18,19,20], [27,28,29]],
     [[21,22,23], [30,31,32]],
     [[24,25,26], [33,34,35]]]

b = [[i for j in k for i in j ] for k in a]
print(b)

outputs:

[ 0,  1,  2,  9, 10, 11]
[ 3,  4,  5, 12, 13, 14]
[ 6,  7,  8, 15, 16, 17]
[18, 19, 20, 27, 28, 29]
[21, 22, 23, 30, 31, 32]
[24, 25, 26, 33, 34, 35]

3 Comments

OP is talking about numpy arrays, not lists
a[0] is not "[[0,1,2], [9,10,11 ]]" it is "[[0,1,2],[3,4,5],[6,7,8],[9,10,11 ],[12,13,14]]"
@HarryReid That wasn't clear from the original post, let me fix that
1

The reshape you ask can be done with:

x = np.arange(36).reshape((4,3,3))
np.vstack(np.hstack(x[2*i:2+2*i]) for i in range(x.shape[0]//2))
>>array([[ 0,  1,  2,  9, 10, 11],
   [ 3,  4,  5, 12, 13, 14],
   [ 6,  7,  8, 15, 16, 17],
   [18, 19, 20, 27, 28, 29],
   [21, 22, 23, 30, 31, 32],
   [24, 25, 26, 33, 34, 35]])

2 Comments

Thanks I appreciate it. Is there a way I can scale it to an array of (400,8,8)? When I try it outputs an array of (1600x16)
Yes, replace the 2's by 20's: np.vstack(np.hstack(x[20*i:20+20*i]) for i in range(x.shape[0]//20)).shape.

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.