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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.