Roman
Roman

Reputation: 3241

Gridding a numpy array

The xx and yy corresponds to the vertices of 9 rectangles. How can I obtain 4 coordinates of each rectangle as tuples?

>>> import numpy as np
>>> xx, yy = np.mgrid[0:4, 10:14]
>>> xx
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3]])
>>> yy
array([[10, 11, 12, 13],
       [10, 11, 12, 13],
       [10, 11, 12, 13],
       [10, 11, 12, 13]])
>>> xx, yy = xx.ravel(), yy.ravel()
>>> xx
array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3])
>>> yy
array([10, 11, 12, 13, 10, 11, 12, 13, 10, 11, 12, 13, 10, 11, 12, 13])
>>> lists = list(zip(xx, yy))
>>> lists
[(0, 10), (0, 11), (0, 12), (0, 13), (1, 10), (1, 11), (1, 12), (1, 13), (2, 10), (2, 11), (2, 12), (2, 13), (3, 10), (3, 11), (3, 12), (3, 13)]

The coordinates of the first rectangle would be:

[(0, 10), (0, 11), (1, 11), (1, 10)].

Similarly, I want to get the coordinates of other 8 rectangles in the format "list of lists".

The order of the coordinates for a rectangle is not important.

NumPy/SciPy approach is preffered.

Upvotes: 2

Views: 185

Answers (2)

Bas Swinckels
Bas Swinckels

Reputation: 18488

One way, without using mgrid:

x = np.arange(4)
y = np.arange(10, 14)
d = [[0,0],[0,1],[1,1],[1,0]]  # define order to go around rectangle here

for ix in range(len(x) - 1):
    for iy in range(len(y) - 1):
        print [(x[ix + dx], y[iy + dy]) for dx, dy in d]

Result:

[(0, 10), (0, 11), (1, 11), (1, 10)]
[(0, 11), (0, 12), (1, 12), (1, 11)]
[(0, 12), (0, 13), (1, 13), (1, 12)]
[(1, 10), (1, 11), (2, 11), (2, 10)]
[(1, 11), (1, 12), (2, 12), (2, 11)]
[(1, 12), (1, 13), (2, 13), (2, 12)]
[(2, 10), (2, 11), (3, 11), (3, 10)]
[(2, 11), (2, 12), (3, 12), (3, 11)]
[(2, 12), (2, 13), (3, 13), (3, 12)]

If you insist in doing it using numpy only, you could do something like this:

xx, yy = np.mgrid[0:4, 10:14]
top = xx[:-1,1:]
bot = xx[1:,1:]
left = yy[1:,:-1]
right = yy[1:,1:]
np.column_stack(v.ravel() 
    for v in (top, left, top, right, bot, right, bot, left))

The result is a single matrix, but the columns are exactly the same as the tuples you want:

array([[ 0, 10,  0, 11,  1, 11,  1, 10],
       [ 0, 11,  0, 12,  1, 12,  1, 11],
       [ 0, 12,  0, 13,  1, 13,  1, 12],
       [ 1, 10,  1, 11,  2, 11,  2, 10],
       [ 1, 11,  1, 12,  2, 12,  2, 11],
       [ 1, 12,  1, 13,  2, 13,  2, 12],
       [ 2, 10,  2, 11,  3, 11,  3, 10],
       [ 2, 11,  2, 12,  3, 12,  3, 11],
       [ 2, 12,  2, 13,  3, 13,  3, 12]])

Upvotes: 2

Adam Smith
Adam Smith

Reputation: 54163

Outside of numpy (because I don't know numpy at all...)

import itertools

result = [list(itertools.product((x,x+1), (y,y+1))) for 
          x,y in itertools.product(range(0,3), range(10,13))]

That results in

[[(0, 10), (0, 11), (1, 10), (1, 11)],
 [(0, 11), (0, 12), (1, 11), (1, 12)],
 [(0, 12), (0, 13), (1, 12), (1, 13)],
 [(1, 10), (1, 11), (2, 10), (2, 11)],
 [(1, 11), (1, 12), (2, 11), (2, 12)],
 [(1, 12), (1, 13), (2, 12), (2, 13)],
 [(2, 10), (2, 11), (3, 10), (3, 11)],
 [(2, 11), (2, 12), (3, 11), (3, 12)],
 [(2, 12), (2, 13), (3, 12), (3, 13)]]

Upvotes: 2

Related Questions