2

I am trying to reshape some arrays into a specific order but numpy.reshape is not solving my problem and I don't want to use any loops unless I really have to.

Let's take an array a with values:

a = [['x1','x2','x3','y1','y2','y3','z1','z2','z3'],
['x4','x5','x6','y4','y5','y6','z4','z5','z6']]

and np.reshape(a,[-1,18]) returns:

array([['x1', 'x2', 'x3', 'y1', 'y2', 'y3', 'z1', 'z2', 'z3', 
     'x4', 'x5','x6', 'y4', 'y5', 'y6', 'z4', 'z5', 'z6']], dtype='<U2')

but is it possible to get a result like this:

[['x1', 'x2', 'x3','x4', 'x5','x6', 'y1', 'y2', 'y3','y4', 'y5', 'y6',
 'z1', 'z2', 'z3', 'z4', 'z5', 'z6']]
0

2 Answers 2

1

You need to reshape and transpose the array:

import numpy as np

a = np.array([['x1','x2','x3','y1','y2','y3','z1','z2','z3'],
              ['x4','x5','x6','y4','y5','y6','z4','z5','z6']])
b = a.reshape(2, 3, 3).transpose((1, 0, 2)).ravel()
print(b)
# ['x1' 'x2' 'x3' 'x4' 'x5' 'x6' 'y1' 'y2' 'y3' 'y4' 'y5' 'y6' 'z1' 'z2'
#  'z3' 'z4' 'z5' 'z6']

Step by step, first you have your initial array.

print(a)
# [['x1' 'x2' 'x3' 'y1' 'y2' 'y3' 'z1' 'z2' 'z3']
#  ['x4' 'x5' 'x6' 'y4' 'y5' 'y6' 'z4' 'z5' 'z6']]

Then you reshape it as "two 3x3 matrices":

print(a.reshape(2, 3, 3))
# [[['x1' 'x2' 'x3']
#   ['y1' 'y2' 'y3']
#   ['z1' 'z2' 'z3']]
#
#  [['x4' 'x5' 'x6']
#   ['y4' 'y5' 'y6']
#   ['z4' 'z5' 'z6']]]

Now if you flattened that, after x3 you would get y1. You need to reorder the axes so after x3 goes x4, which means you first want to iterate the columns (x1, x2, x3), then jump to the next matrix to iterate the columns in its first rows (x4, x5, x6) and then continue to the next row of the first matrix. So the innermost dimensions should be the same (the columns), but you have to swap the first two dimensions so you first change matrix and then rows instead of the other way around:

print(a.reshape(2, 3, 3).transpose((1, 0, 2)))
# [[['x1' 'x2' 'x3']
#   ['x4' 'x5' 'x6']]
#
#  [['y1' 'y2' 'y3']
#   ['y4' 'y5' 'y6']]
#
#  [['z1' 'z2' 'z3']
#   ['z4' 'z5' 'z6']]]

Now than can be flattened to get the desired result.

print(a.reshape(2, 3, 3).transpose((1, 0, 2)).ravel())
# ['x1' 'x2' 'x3' 'x4' 'x5' 'x6' 'y1' 'y2' 'y3' 'y4' 'y5' 'y6' 'z1' 'z2'
#  'z3' 'z4' 'z5' 'z6']
Sign up to request clarification or add additional context in comments.

Comments

1

If the lengths of the x,yand z values are the same, you could use np.array_split and flatten the result with .ravel():

np.array(np.array_split(a, 3, axis=1)).ravel()

array(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'y1', 'y2', 'y3', 'y4', 'y5',
       'y6', 'z1', 'z2', 'z3', 'z4', 'z5', 'z6'], dtype='<U2')

Comments

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.