1

I have a three individual lists in Python, all of which are quite large. A stipulation is that the lists cannot be reordered from how they are currently shown. A snippet of how each list looks is as follows:

lats = [40.92322342,40.92322342,40.92322342,40.92322342,40.92322342] lons = [-74.32176109,-74.29518277,-74.26860445,-74.24202613,-74.21544781] data = [19,19,19,17,18]

I am looking to provide a latitude and longitude pairing, and would like to return the index number and corresponding value of the data list that matches the closest to both the provided latitude and longitude.

For example, the pairing 40.9254, -74.2765 would return the corresponding index number, which would be the third set of values in the list snippet provided above.

Using this example, I've been able to partition this search by individual list and return the corresponding index number. However, the index numbers are different.

Code:

min(enumerate(lats), key=lambda x: abs(x[1]-40.9254)) min(enumerate(lons), key=lambda x: abs(x[1]-(-74.2765)))

an index #, 40.92322342 a different index # than above, -74.26860445

Are there any effective ways to solve this problem?

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
TornadoEric
  • 399
  • 3
  • 16
  • What does mean your *a different index # than above*? the `lats` contains identical values in your input – RomanPerekhrest Oct 27 '19 at 17:06
  • 1
    You need to define `matches the closest` in terms of *both* lat and lon. Maybe something like the sum of the absolute value of the differences. You can't look at them individually. – Mark Oct 27 '19 at 17:11

2 Answers2

1

You could first find the euclidean distance between two points using sqrt((x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2), then use it combined with min() as a key to find the closest point.

from math import sqrt

lats = [40.92322342,40.92322342,40.92322342,40.92322342,40.92322342]
lons = [-74.32176109,-74.29518277,-74.26860445,-74.24202613,-74.21544781]

def euclidean_distance(x, y):
    return sqrt((x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2)

def find_closest_point(data, point):
    # create (point, index) pairs
    indices = ((e, i) for i, e in enumerate(data))

    # find smallest point, and only return the index
    return min(indices, key=lambda p: euclidean_distance(p[0], point))[1]

print(find_closest_point(zip(lats, lons), (40.9254, -74.2765)))

Which returns the third pair of coordinates(indexing starting at 0):

2

Note: You could have lats and lons in a list of tuples to begin with, then you don't need to call zip() in the function.

RoadRunner
  • 25,803
  • 6
  • 42
  • 75
0

Why not make an object for Lattitude and Longitude.

class LatLong:

      def __init__(self, lat, lon):
          self.lat = lat
          self.lon = lon

Then create a single list of objects and for a given lat and long, just loop through the object list and return the object

bigbounty
  • 16,526
  • 5
  • 37
  • 65