Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I am trying to convert a string into n-dimensioned numpy array (x, 4, 4). Basic requirement is 4x4 array with column major filling of values. We will use as many 4x4 arrays as per the length of the input string. For example if my string is:

'A quick brown fox jumps over dog'

The resultant array should look like this:

[[['A' 'i' 'b' 'n']
  [' ' 'c' 'r' ' ']
  ['q' 'k' 'o' 'f']
  ['u' ' ' 'w' 'o']]

 [['x' 'm' 'o' ' ']
  [' ' 'p' 'v' 'd']
  ['j' 's' 'e' 'o']
  ['u' ' ' 'r' 'g']]]

Note that instead of the conventional row-first filling of values requirement is for the filling to be column first within the 4x4 subarray.

I understand the conventional code for achieving this would be something like below with a triple-nested loop:

string = 'A quick brown fox jumps over dog'
dim1 = len(string) // 16
matrix1 = np.empty((dim1, 4, 4), str)
position = 0
for z in range(dim1):
    for y in range(4):
        for x in range(4):
            matrix1[z, x, y] = string[position]
            position += 1
print(matrix1)

I wanted to use functional power of Python, so after some research I found the following method:

string = 'A quick brown fox jumps over dog'
dim1 = len(string) // 16
matrix2 = np.array(list(string))
matrix2 = np.reshape(matrix2, (dim1, 4, 4))

But when I do the reshape, it gives me the following output:

[[['A' ' ' 'q' 'u']
  ['i' 'c' 'k' ' ']
  ['b' 'r' 'o' 'w']
  ['n' ' ' 'f' 'o']]

 [['x' ' ' 'j' 'u']
  ['m' 'p' ' ' 'o']
  ['v' 'e' 'r' ' ']
  ['d' 'o' 'g' 's']]]

which is completing the string row by row. I want it column by column within the sub (4x4) array and then move on to the next (4x4) one.

Further research showed that I can use the swapaxes function to achieve this, as below:

matrix2 = np.swapaxes(matrix2, 1, 2)

The above gives me the desired result.

So, my final code becomes:

string = 'A quick brown fox jumps over dog'
dim1 = len(string) // 16
matrix2 = np.array(list(string))
matrix2 = np.reshape(matrix2, (dim1, 4, 4))
matrix2 = np.swapaxes(matrix2, 1, 2)
print(matrix2)

Just wanted your expert opinions if there is a way to achieve the reshape and swapaxes using a single method/function. Or if there is a totally better, more convenient method without using loops or without using so many functions.

share|improve this question
1  
Don't be afraid of using functions like reshape and swapaxes. They are not expensive (timewise). An unusual layout requires special actions. – hpaulj Aug 14 '15 at 16:26
up vote 2 down vote accepted

Not a single method/function, but you can do this in a one-liner:

matrix2 = np.array(list(string)).reshape(dim1,4,4).swapaxes(1,2)

which gives:

array([[['A', 'i', 'b', 'n'],
        [' ', 'c', 'r', ' '],
        ['q', 'k', 'o', 'f'],
        ['u', ' ', 'w', 'o']],

       [['x', 'm', 'o', ' '],
        [' ', 'p', 'v', 'd'],
        ['j', 's', 'e', 'o'],
        ['u', ' ', 'r', 'g']]], 
      dtype='|S1')
share|improve this answer
    
Thanks for your response. You mean otherwise I am using the right functions? I meant that is this efficient use of python numpy powers or there is a simpler more powerful way to achieve the same result. – Abdul Qadir Aug 14 '15 at 16:23
    
There may be other ways to do it, but if this gives you the right result, it is the "right" function :) As @hpaulj says, reshape and swapaxes are not particularly expensive, so I wouldn't try too hard to find an alternative solution – tom Aug 14 '15 at 16:31
    
tom and @hpaulj thanks. when you say not particularly expensive, even if the string is long like 1000+ characters this would still remain efficient? If so, i agree and will take your suggestion of not looking any further. appreciate your help guys. – Abdul Qadir Aug 14 '15 at 16:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.