Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Map coordinates to cells defined by numpy.meshgrid

I have many (x,y) coordinates on a picture stimulus and I want to

  1. Divide the entire size of the picture into several small cells
  2. Give each cell a name (e.g., A, B, C, D....)
  3. Map each point to the corresponding cell.

For example:

import numpy as np
n = 5

x = np.linspace(0, 10, n)
y = np.linspace(0, 10, n)

xv, yv = np.meshgrid(x, y, indexing='xy')

np.array([xv, yv])

array([[[  0. ,   2.5,   5. ,   7.5,  10. ],
    [  0. ,   2.5,   5. ,   7.5,  10. ],
    [  0. ,   2.5,   5. ,   7.5,  10. ],
    [  0. ,   2.5,   5. ,   7.5,  10. ],
    [  0. ,   2.5,   5. ,   7.5,  10. ]],

   [[  0. ,   0. ,   0. ,   0. ,   0. ],
    [  2.5,   2.5,   2.5,   2.5,   2.5],
    [  5. ,   5. ,   5. ,   5. ,   5. ],
    [  7.5,   7.5,   7.5,   7.5,   7.5],
    [ 10. ,  10. ,  10. ,  10. ,  10. ]]])

If I have a big list of points (x,y)

points = [(1,3), (2,4), (0.4, 0.8), (3.5, 7.9), ...]

What I want to get is a pandas data frame with one column as the coordinates and one column as the cell names. For example, for the above four points if I get these cell names:

location = ['A','K','B','F']

Then I can create a data frame:

pd.DataFrame({'points': points,'location':location})

I want to know how to get the corresponding cell names (i.e. location). Constructing a dataframe from there is easy. Because I have a lot of cells and a lot of coordinates, I was wondering what is an efficient way to do this. The order of the cell names doesn't matter as long as each one is unique. If a point happens to sit on the cell boundary we can simply return np.nan.

like image 705
Han Zhang Avatar asked Dec 01 '25 01:12

Han Zhang


1 Answers

If you divide a (N*M) picture into n*m cells like this (n=4,m=3):

A B C D
E F G H
I J K L

You can get the cell-row and -column by using np.digitize and from them find the corresponding letter.

In [115]: N, M = (10, 10)

In [116]: n, m = (4, 3)

In [117]: x_boundries = np.linspace(0, N, n+1)

In [118]: y_boundries = np.linspace(0, M, m+1)

In [119]: letters = np.array([chr(65+i) for i in range(n*m)]).reshape((m, n))

In [120]: letters
Out[120]: 
array([['A', 'B', 'C', 'D'],
       ['E', 'F', 'G', 'H'],
       ['I', 'J', 'K', 'L']], dtype='<U1')

In [121]: points = [(1,3), (2,4), (0.4, 0.8), (3.5, 7.9)]

In [122]: xs, ys  = zip(*points)

In [123]: xs, ys
Out[123]: ((1, 2, 0.4, 3.5), (3, 4, 0.8, 7.9))

In [124]: cell_row = np.digitize(ys, y_boundries)-1

In [125]: cell_column = np.digitize(xs, x_boundries)-1

In [126]: cell_row, cell_column
Out[126]: (array([0, 1, 0, 2]), array([0, 0, 0, 1]))

In [127]: locations = letters[cell_row, cell_column]

In [128]: locations
Out[128]: array(['A', 'E', 'A', 'J'], dtype='<U1')
like image 98
kuppern87 Avatar answered Dec 03 '25 22:12

kuppern87



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!