Efficiently find indices of nearest points on non-rectangular 2D grid

2024/9/27 19:25:13

I have an irregular (non-rectangular) lon/lat grid and a bunch of points in lon/lat coordinates, which should correspond to points on the grid (though they might be slightly off for numerical reasons). Now I need the indices of the corresponding lon/lat points.

I have written a function which does this, but it is REALLY slow.

def find_indices(lon,lat,x,y):lonlat = np.dstack([lon,lat])delta = np.abs(lonlat-[x,y])ij_1d = np.linalg.norm(delta,axis=2).argmin()i,j = np.unravel_index(ij_1d,lon.shape)return i,jind = [find_indices(lon,lat,p*) for p in points]

I'm pretty sure there's a better (and faster) solution in numpy/scipy. I've already googled quite a lot, but the answer has so far eluded me.

Any suggestions on how to efficiently find the indices of the corresponding (nearest) points?

PS: This question emerged from another one).

Answer

If the points are sufficiently localized, you may try directly scipy.spatial's cKDTree implementation, as discussed by myself in another post. That post was about interpolation but you can ignore that and just use the query part.

tl;dr version:

Read up the documentation of scipy.sptial.cKDTree. Create the tree by passing an (n, m)-shaped numpy ndarray object to the initializer, and the tree will be created from the n m-dimensional coordinates.

tree = scipy.spatial.cKDTree(array_of_coordinates)

After that, use tree.query() to retrieve the k-th nearest neighbor (possibly with approximation and parallelization, see docs), or use tree.query_ball_point() to find all neighbors within given distance tolerance.

If the points are not well localized, and the spherical curvature / non-trivial topology kicks in, you can try breaking the manifold into multiple parts, each small enough to be considered local.

https://en.xdnf.cn/q/71427.html

Related Q&A

How to code a sequence to sequence RNN in keras?

I am trying to write a sequence to sequence RNN in keras. I coded this program using what I understood from the web. I first tokenized the text then converted the text into sequence and padded to form …

Error when installing psycopg2 on Windows 10

Collecting psycopg2Using cached psycopg2-2.6.1.tar.gzComplete output from command python setup.py egg_info:running egg_infocreating pip-egg-info\psycopg2.egg-infowriting pip-egg-info\psycopg2.egg-info\…

Speeding up Pandas apply function

For a relatively big Pandas DataFrame (a few 100k rows), Id like to create a series that is a result of an apply function. The problem is that the function is not very fast and I was hoping that it can…

Numpy repeat for 2d array

Given two arrays, say arr = array([10, 24, 24, 24, 1, 21, 1, 21, 0, 0], dtype=int32) rep = array([3, 2, 2, 0, 0, 0, 0, 0, 0, 0], dtype=int32)np.repeat(arr, rep) returns array([10, 10, 10, 24, 24, 2…

Python Linux route table lookup

I posted Python find first network hop about trying to find the first hop and the more I thought about it, the easier it seemed like it would be a process the routing table in python. Im not a program…

How to compare frequencies/sampling rates in pandas?

is there a way to say that 13Min is > 59S and <2H using the frequency notation in pandas?

Why do I get expected an indented block when I try to run my Python script? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.Closed 5 years ago.Edit the question to include desired behavior, a specific problem or error, and t…

python run command as normal user in a root script

I have a python script that is launched as root, I cant change it. I would like to know if its possible to exectute certain lines of this script (or all the script) as normal user (I dont need to be ro…

Compare values of two arrays in python

How can i check if item in b is in a and the found match item in a should not be use in the next matching? Currently this code will match both 2 in b.a = [3,2,5,4] b = [2,4,2]for i in b:if i in a:prin…

How to count the number of digits in numbers in different bases?

Im working with numbers in different bases (base-10, base-8, base-16, etc). Im trying to count the number of characters in each number. ExampleNumber: ABCDEF Number of digits: 6I know about the method …