-1

Similar to the answer for simple 1D arrays posted here: https://stackoverflow.com/a/38163917/15473622

I would like to split a large 2D array (representing an elevation raster dataset), into smaller 2D arrays (tiles WITH a certain overlap). Given the following array:

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

Where the input variables would be:

height = 3
width = 4
overlap = 1 *or* y-step = 2, x-step = 3

You would get the following tiles (the last rows and columns can be smaller if the edge arrays are not perfectly divisible). Note B[4] is completely surrounded by a 1 cell buffer and the edge tiles do not extend beyond the original array extents:

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

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

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

The tile overlap is necessary for further terrain processing on the smaller tiles to eliminate any edge effects when merged back together later.

Is there an elegant way to do this? Many thanks in advance! (And thank you Julien for correcting my original logic!)

GioGee
  • 1
  • 1

1 Answers1

0

Your example doesn't seem to fully correspond to your logic (it seems to imply the last column alone should also be selected)... So please clarify or just adapt this simple 1-liner to your exact need:

A = [[1,2,3,4,5,6,7,8,9,0],
     [2,3,4,5,6,7,8,9,0,1],
     [3,4,5,6,7,8,9,0,1,2],
     [4,5,6,7,8,9,0,1,2,3],
     [5,6,7,8,9,0,1,2,3,4],
     [6,7,8,9,0,1,2,3,4,5]]
A = np.array(A)

height = 3
width = 4
overlap = 1
y_step = height-overlap 
x_step = width-overlap

B = [A[y:y+height,x:x+width] for y in range(0, A.shape[0], y_step) for x in range(0, A.shape[1], x_step)]
Julien
  • 13,986
  • 5
  • 29
  • 53
  • Thanks Julien for catching my mistake! I clarified my question above adding a new line to Array A and modifying the desired tiled output in Array B. Note Array B can optionally be a whole bunch of smaller separate arrays too. I left the input parameters unchanged. Does this change your solution much? – GioGee Mar 25 '21 at 14:02