6

I have an array of numbers whose shape is 26*43264. I would like to reshape this into an array of shape 208*208 but in chunks of 26*26.

[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10,11,12,13,14,15,16,17,18,19]]

becomes something like:

[[0, 1, 2, 3, 4],
[10,11,12,13,14],
[ 5, 6, 7, 8, 9],
[15,16,17,18,19]]
3
  • since 43264=208*208 you could reshape your array to a shape of 26*208*208 but not 208*208 * 26*26 Commented Nov 10, 2015 at 15:28
  • are you just looking for np.reshape(list,(4,5))? Commented Nov 10, 2015 at 15:31
  • Just doing np.reshape(list, (4,5)) doesn't work because it segments the data incorrectly. Commented Nov 10, 2015 at 15:53

2 Answers 2

6

This kind of reshaping question has come up before. But rather than search I'll quickly demonstate a numpy approach

make your sample array:

In [473]: x=np.arange(20).reshape(2,10)
In [474]: x
Out[474]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])

Use reshape to split it into blocks of 5

In [475]: x.reshape(2,2,5)
Out[475]: 
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9]],

       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]]])

and use transpose to reorder dimensions, and in effect reorder those rows

In [476]: x.reshape(2,2,5).transpose(1,0,2)
Out[476]: 
array([[[ 0,  1,  2,  3,  4],
        [10, 11, 12, 13, 14]],

       [[ 5,  6,  7,  8,  9],
        [15, 16, 17, 18, 19]]])

and another shape to consolidate the 1st 2 dimensions

In [477]: x.reshape(2,2,5).transpose(1,0,2).reshape(4,5)
Out[477]: 
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19]])

If x is already a numpy array, these transpose and reshape operations are cheap (time wise). If x was really nested lists, then the other solution with list operations will be faster, since making a numpy array has overhead.

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

Comments

1

A little ugly, but here's a one-liner for the small example that you should be able to modify for the full size one:

In [29]: from itertools import chain

In [30]: np.array(list(chain(*[np.arange(20).reshape(4,5)[i::2] for i in xrange(2)])))
Out[30]:
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19]])

EDIT: Here's a more generalized version in a function. Uglier code, but the function just takes an array and a number of segments you'd like to end up with.

In [57]: def break_arr(arr, chunks):
   ....:     to_take = arr.shape[1]/chunks
   ....:     return np.array(list(chain(*[arr.take(xrange(x*to_take, x*to_take+to_take), axis=1) for x in xrange(chunks)])))
   ....:

In [58]: arr = np.arange(40).reshape(4,10)

In [59]: break_arr(arr, 5)
Out[59]:
array([[ 0,  1],
       [10, 11],
       [20, 21],
       [30, 31],
       [ 2,  3],
       [12, 13],
       [22, 23],
       [32, 33],
       [ 4,  5],
       [14, 15],
       [24, 25],
       [34, 35],
       [ 6,  7],
       [16, 17],
       [26, 27],
       [36, 37],
       [ 8,  9],
       [18, 19],
       [28, 29],
       [38, 39]])

In [60]: break_arr(arr, 2)
Out[60]:
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19],
       [25, 26, 27, 28, 29],
       [35, 36, 37, 38, 39]])

1 Comment

So how would this be adapted to work with a larger array of integers?

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.