1

I want to divide a 4x4 array into a list of list of four 2x2 array. This

| 0   1   2   3 |
| 4   5   6   7 |
| 8   9  10  11 |
|12   13 14  15 | 

should be divided into four blocks as

| |0   1|  |2   3 | |
| |4   5|  |6   7 | |
|                   |
| | 8   9| |10  11| |
| |12  13| |14  15| | 

so, if I access block 1 then it should be [2,3],[6,7].

I wrote this method:

from numpy import *
from operator import itemgetter

def divide_in_blocks(A):
    A1 = hsplit(A, A[0].size/2)
    for i, x in enumerate(A1):
        A1[i] = vsplit(x, x.size/4)
    return A1

if __name__ == '__main__':
    a = arange(16).reshape(4,4)
    a1 = divide_in_blocks(a)
    #print a
    #a1 = sorted(a1, key=itemgetter(2))
    print a1  

which divides the array as

| |0   1|  | 8   9 | |
| |4   5|  |12  13 | |
|                    |
| |2   3|  |10   11| |
| |6   7|  |14   15| | 

i.e. I am getting block 1 as [8, 9], [12, 13].

Output of the code:

[[array([[0, 1],
         [4, 5]]), 
  array([[ 8,  9],
         [12, 13]])], 
 [array([[2, 3],
         [6, 7]]), 
  array([[10, 11],
         [14, 15]])]]  

Is there any way to sort this list of list of arrays to get the desired output:

 [[array([[0, 1],
         [4, 5]]),
  array([[2, 3],
         [6, 7]])], 
 [array([[ 8,  9],
         [12, 13]]), 
  array([[10, 11],
         [14, 15]])]]  

?

1
  • you can convert to python normal list and do sorting of the lists within the main list. Commented Nov 6, 2014 at 15:33

4 Answers 4

2

I would just use array slices

>>> blocksize = 2
>>> h, w = a.shape
>>> rows = xrange(0, h, blocksize)
>>> cols = xrange(0, w, blocksize)
>>> [[a[row:row+blocksize, col:col+blocksize] for col in cols] for row in rows]

[[array([[0, 1],
         [4, 5]]), array([[2, 3],
         [6, 7]])], [array([[ 8,  9],
         [12, 13]]), array([[10, 11],
         [14, 15]])]]
Sign up to request clarification or add additional context in comments.

1 Comment

I am already getting this as output :). What I want is [array([[2, 3], [6, 7]]) just after array([[0, 1], [4, 5]])
1

This can be done directly with reshape and transpose:

> a = np.arange(16).reshape((4, 4))
> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

> a.reshape((2, 2, 2, 2)).transpose((0, 2, 1, 3))
array([[[[ 0,  1],
         [ 4,  5]],

        [[ 2,  3],
         [ 6,  7]]],


       [[[ 8,  9],
         [12, 13]],

        [[10, 11],
         [14, 15]]]])

1 Comment

Wow. Actually I wanted this 4D array via list of list of array. You just simplify this. Nice :)
0

A bit dirty, but it can be done by list comprehension:

a = arange(16).reshape(4,4)

a = [a[x:x+2,y:y+2] for x in range(0,4,2) for y in range(0,4,2)]

a
[array([[0, 1],
        [4, 5]]), array([[2, 3],
        [6, 7]]), array([[ 8,  9],
        [12, 13]]), array([[10, 11],
        [14, 15]])]

Comments

0
import numpy as np

def split2x2(a,n):
    if n%2: return None
    shapes = ((0,n/2,0,n/2), (0,n/2,n/2,n),
              (n/2,n,0,n/2), (n/2,n,n/2,n))
    return [a[r0:r1,c0:c1] for  r0, r1, c0, c1 in shapes]

a = np.array(((0,0,0,0,1,1,1,1),
              (0,0,0,0,1,1,1,1),
              (0,0,0,0,1,1,1,1),
              (0,0,0,0,1,1,1,1),
              (2,2,2,2,3,3,3,3),
              (2,2,2,2,3,3,3,3),
              (2,2,2,2,3,3,3,3),
              (2,2,2,2,3,3,3,3),))

l_a = split2x2(a,len(a))
print l_a[1]

Output

# [[1 1 1 1]
#  [1 1 1 1]
#  [1 1 1 1]
#  [1 1 1 1]]

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.