0

any one know how to retrieve section from this array:

a=[[1, 3, 2, 5, 7, 9, 4, 6, 8],
  [4, 9, 8, 2, 6, 1, 3, 7, 5],
  [7, 5, 6, 3, 8, 4, 2, 1, 9],
  [6, 4, 3, 1, 5, 8, 7, 9, 2],
  [5, 2, 1, 7, 9, 3, 8, 4, 6],
  [9, 8, 7, 4, 2, 6, 5, 3, 1],
  [2, 1, 4, 9, 3, 5, 6, 8, 7],
  [3, 6, 5, 8, 1, 7, 9, 2, 4],
  [8, 7, 9, 6, 4, 2, 1, 5, 3]]

I mean that i would like to retrieve section 3X3 ,for example,the top left one is:

[[1,3,2],
 [4,9,8],
 [7,5,6]]

the sections needed to be retrieved are :

left section

[[0:3,0:3]],[[3:6,0:3]],[[6:9,0:3]]

middle section

[[0:3,3:6]],[[3:6,3:6]],[[6:9,3:6]]

right section

[[0:3,6:9]],[[3:6,6:9]],[[6:9,6:9]]

How to retrieve all these sections? Is it necessary to use numpy?

simonchou
  • 61
  • 1
  • 9
  • Are you looking to extract sliding sections/windows? To put it another way - What must be the next section after the top left one? – Divakar Jul 21 '16 at 08:54
  • 1
    Numpy isn't necessary : [List comprehention](http://carlgroner.me/Python/2011/11/09/An-Introduction-to-List-Comprehensions-in-Python.html) is what you need – pwnsauce Jul 21 '16 at 08:54
  • Possible duplicate of [How do you split a list into evenly sized chunks in Python?](http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python) – Alexandre Beaudet Jul 21 '16 at 08:55
  • i already updated the details.i need to retrieve all these sections which consist of 1-9.list comprehention wont give me the 3X3 list... – simonchou Jul 21 '16 at 09:06

4 Answers4

3

Here's a vectorized approach using reshaping and permuting dimensions -

a.reshape(3,3,3,3).transpose(2,0,1,3).reshape(9,3,3)

Sample run -

In [197]: a
Out[197]: 
array([[1, 3, 2, 5, 7, 9, 4, 6, 8],
       [4, 9, 8, 2, 6, 1, 3, 7, 5],
       [7, 5, 6, 3, 8, 4, 2, 1, 9],
       [6, 4, 3, 1, 5, 8, 7, 9, 2],
       [5, 2, 1, 7, 9, 3, 8, 4, 6],
       [9, 8, 7, 4, 2, 6, 5, 3, 1],
       [2, 1, 4, 9, 3, 5, 6, 8, 7],
       [3, 6, 5, 8, 1, 7, 9, 2, 4],
       [8, 7, 9, 6, 4, 2, 1, 5, 3]])

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

       [[6, 4, 3],
        [5, 2, 1],
        [9, 8, 7]],

       [[2, 1, 4],
        [3, 6, 5],
        [8, 7, 9]], ....

If you need to flatten each such section/window, just tweak the last reshaping, like so -

In [199]: a.reshape(3,3,3,3).transpose(2,0,1,3).reshape(9,9)
Out[199]: 
array([[1, 3, 2, 4, 9, 8, 7, 5, 6],
       [6, 4, 3, 5, 2, 1, 9, 8, 7],
       [2, 1, 4, 3, 6, 5, 8, 7, 9],
       [5, 7, 9, 2, 6, 1, 3, 8, 4],
       [1, 5, 8, 7, 9, 3, 4, 2, 6],
       [9, 3, 5, 8, 1, 7, 6, 4, 2],
       [4, 6, 8, 3, 7, 5, 2, 1, 9],
       [7, 9, 2, 8, 4, 6, 5, 3, 1],
       [6, 8, 7, 9, 2, 4, 1, 5, 3]])
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • Wow I wasn't aware we could do that with `reshape()` and `transpose()` ! (but list comprehention seems smoother) – pwnsauce Jul 21 '16 at 09:38
  • @pwnsauce It's just a performance thing that we try to avoid loops when working with arrays :) – Divakar Jul 21 '16 at 09:42
  • I try to write a function to retrieve these sections like @Em L's answer,but i failed.using numpy would save time and effort .thanks ,you guys are best! – simonchou Jul 21 '16 at 09:49
1

Here is the answer, using list comprehension

>>> [x[:3] for x in a[:3]]
[[1, 3, 2], [4, 9, 8], [7, 5, 6]]

Left section :

[x[0:3] for x in a[0:3]]
[x[0:3] for x in a[3:6]]
[x[0:3] for x in a[6:9]]

Middle section :

[x[3:6] for x in a[0:3]]
[x[3:6] for x in a[3:6]]
[x[3:6] for x in a[6:9]]

Right section :

[x[6:9] for x in a[0:3]]
[x[6:9] for x in a[3:6]]
[x[6:9] for x in a[6:9]]

a[i:j] takes the line from index i to j-1 x[i,j] takes the element of index i to j-1 for said lines

To create 'flattened' lists, using the input from pwnsauce's comment :

Left section :

[x for b in [x[0:3] for x in a[0:3]] for x in b]
[x for b in [x[0:3] for x in a[3:6]] for x in b]
[x for b in [x[0:3] for x in a[6:9]] for x in b]

Middle section :

[x for b in [x[3:6] for x in a[0:3]] for x in b]
[x for b in [x[3:6] for x in a[3:6]] for x in b]
[x for b in [x[3:6] for x in a[6:9]] for x in b]

Right section :

[x for b in [x[6:9] for x in a[0:3]] for x in b]
[x for b in [x[6:9] for x in a[3:6]] for x in b]
[x for b in [x[6:9] for x in a[6:9]] for x in b]
HolyDanna
  • 609
  • 4
  • 13
  • thanks Danna,but it wont be easy to put this into a function...because after i get these sections ,i need to flatten them into a list like [1,2,3,4,5,6,7,8,9]. – simonchou Jul 21 '16 at 09:12
  • @simonchou to flatten them I would advise you to use : List comprehention \o/ – pwnsauce Jul 21 '16 at 09:19
  • 1
    @simonch `flatten_list = [x for b in [x[:3] for x in a[:3]] for x in b]` (this return de left section flattened. the `[x[:3] for x in a[:3]]` is the left section not flat – pwnsauce Jul 21 '16 at 09:27
  • @pwnsauce my bad, didn't see my mistake. Thanks for your input – HolyDanna Jul 21 '16 at 09:32
  • @simonchou See if the second part (for lattened list, using pwsauce's comment) do what you need. – HolyDanna Jul 21 '16 at 09:35
0

You can use similar this:

for i in range(0, len(a), 3):
    left_section = []
    middle_section = []
    right_section = []
    left_section.append(a[i][:3])
    left_section.append(a[i+1][:3])
    left_section.append(a[i+2][:3])
    middle_section.append(a[i][3:6])
    middle_section.append(a[i+1][3:6])
    middle_section.append(a[i+2][3:6])
    right_section.append(a[i][3:6])
    right_section.append(a[i+1][3:6])
    right_section.append(a[i+2][3:6])
    print(left_section)
    print(middle_section)
    print(right_section)

OR

for i in range(0, len(a), 3):
    left_section = []
    middle_section = []
    right_section = []
    left_section.extend(a[i][:3])
    left_section.extend(a[i+1][:3])
    left_section.extend(a[i+2][:3])
    middle_section.extend(a[i][3:6])
    middle_section.extend(a[i+1][3:6])
    middle_section.extend(a[i+2][3:6])
    right_section.extend(a[i][3:6])
    right_section.extend(a[i+1][3:6])
    right_section.extend(a[i+2][3:6])
    print(left_section)
    print(middle_section)
    print(right_section)
Em L
  • 328
  • 1
  • 7
0

Pure python way without the use of numpy:

As you need the lists flattened we use this function (as already mentioned):

def flatten_list(li):
    return [el for sub_li in li for el in sub_li]

We know we can retrieve the first section like this:

flatten_list([a[row][0:3] for row in range(3)]) # retrieves the first section
>>> [1, 3, 2, 4, 9, 8, 7, 5, 6]

and all left_sections like:

[flatten_list([a[row][0:3] for row in range(y*3, y*3+3)]) for y in range(3)]
>>> [[1, 3, 2, 4, 9, 8, 7, 5, 6], [6, 4, 3, 5, 2, 1, 9, 8, 7], [2, 1, 4, 3, 6, 5, 8, 7, 9]]

all together:

[[flatten_list([a[row][x*3:x*3+3] for row in range(y*3, y*3+3)]) for y in range(3)] for x in range(3)]
>>> [[[1, 3, 2, 4, 9, 8, 7, 5, 6],
      [6, 4, 3, 5, 2, 1, 9, 8, 7],
      [2, 1, 4, 3, 6, 5, 8, 7, 9]],
     [[5, 7, 9, 2, 6, 1, 3, 8, 4],
      [1, 5, 8, 7, 9, 3, 4, 2, 6],
      [9, 3, 5, 8, 1, 7, 6, 4, 2]],
     [[4, 6, 8, 3, 7, 5, 2, 1, 9],
      [7, 9, 2, 8, 4, 6, 5, 3, 1],
      [6, 8, 7, 9, 2, 4, 1, 5, 3]]]
Fabbi
  • 11
  • 2