查找一对GPS坐标属于哪一行的有效方法
Efficient way to find which row a pair of GPS coordinates belong to
我有一个带有一组 GPS lat/long 坐标的数据框(称之为 A)
Lat | Long
28.6752213, 77.09311140000001
我有另一个 CSV(有很多行,超过一百万 - 称之为 B)的形式
这基本上是一个网格,具有 4 个角的 lat/long 坐标。
问题
我需要找到 A 中的每一行,它在 B 中以哪一行(非唯一)为界。例如,gps 坐标位于方框内,如 B 中的行所述。我有一个函数 returns True/False
当给定来自 A 的坐标和 B 中的行时
现在我正在使用暴力破解方法,遍历整个 B 数据框并检查每一行是否属于该框。然而,这是非常低效且非常缓慢的。
我相信一定有更好的方法来解决这个问题,因为这是一个常见问题。任何人都可以指点我吗?
谢谢! :)
编辑:
我用来查找特定 gps_coord 是否属于由行
定义的框的函数代码
import matplotlib.path as path
def find_if_point_in_bounding_box(row,gps_coords):
top_left_lat = row['top_left_lat']
top_left_long = row['top_left_long']
top_right_lat = row['top_right_lat']
top_right_long = row['top_right_long']
bottom_left_lat = row['bottom_left_lat']
bottom_left_long = row['bottom_left_long']
bottom_right_lat = row['bottom_right_lat']
bottom_right_long = row['bottom_right_long']
lat,long = gps_coords
# create box
p = path.Path([(top_left_lat, top_left_long),(top_right_lat,top_right_long),(bottom_left_lat,bottom_left_long),(bottom_right_lat,bottom_right_long)])
res = p.contains_points([(lat,long)])[0]
return res
您的 8 个坐标每个仅包含 4 个唯一值:2 个纬度(形成每个框的顶部和底部边界,或北向和南向边界)和两个经度(左右边界,西风和东风)。在 4 个角的 4 个(纬度、经度)组合之间,您会看到有重复值。您只需将您的位置与 4 个边界进行比较,纬度应该落在两个纬度边界之间(或之上),经度应该落在两个经度边界之间。
因此,您可以简单地根据纬度 top_*_lat
和 bottom_*_lat
中的每一个以及 *_left_long
和 [=14 中的每一个来请求具有匹配边界框的行=] 经度:
lat, long = <latitude>, <longitude>
matching_rows = df.query(
# top and bottom latitudes, top lat > bottom lat, north to south
"top_left_lat >= @lat >= bottom_right_lat and "
# left and right longitudes, left long < right long, west to east
"top_left_long <= @long <= bottom_right_long"
)
上面的 pandas.DataFrame.query()
expression 只是做了一个简单的几何点包含测试,并假设您的边界框不跨越 anti-meridian(国际日期变更线)也不与任何一极重叠。
您必须对输入数据框中的每个位置执行此操作; Pandas 无法基于任意表达式合并数据帧(目前)。您可以按两个坐标之一对输入进行分组,以生成与该坐标匹配的行子集,然后在每个组的第二个坐标上进一步过滤它们。
如果您的输入数据帧也非常大,那么使用数据库进行这样的连接可能会更好。
我有一个带有一组 GPS lat/long 坐标的数据框(称之为 A)
Lat | Long
28.6752213, 77.09311140000001
我有另一个 CSV(有很多行,超过一百万 - 称之为 B)的形式
这基本上是一个网格,具有 4 个角的 lat/long 坐标。
问题
我需要找到 A 中的每一行,它在 B 中以哪一行(非唯一)为界。例如,gps 坐标位于方框内,如 B 中的行所述。我有一个函数 returns True/False
当给定来自 A 的坐标和 B 中的行时
现在我正在使用暴力破解方法,遍历整个 B 数据框并检查每一行是否属于该框。然而,这是非常低效且非常缓慢的。
我相信一定有更好的方法来解决这个问题,因为这是一个常见问题。任何人都可以指点我吗?
谢谢! :)
编辑:
我用来查找特定 gps_coord 是否属于由行
定义的框的函数代码import matplotlib.path as path
def find_if_point_in_bounding_box(row,gps_coords):
top_left_lat = row['top_left_lat']
top_left_long = row['top_left_long']
top_right_lat = row['top_right_lat']
top_right_long = row['top_right_long']
bottom_left_lat = row['bottom_left_lat']
bottom_left_long = row['bottom_left_long']
bottom_right_lat = row['bottom_right_lat']
bottom_right_long = row['bottom_right_long']
lat,long = gps_coords
# create box
p = path.Path([(top_left_lat, top_left_long),(top_right_lat,top_right_long),(bottom_left_lat,bottom_left_long),(bottom_right_lat,bottom_right_long)])
res = p.contains_points([(lat,long)])[0]
return res
您的 8 个坐标每个仅包含 4 个唯一值:2 个纬度(形成每个框的顶部和底部边界,或北向和南向边界)和两个经度(左右边界,西风和东风)。在 4 个角的 4 个(纬度、经度)组合之间,您会看到有重复值。您只需将您的位置与 4 个边界进行比较,纬度应该落在两个纬度边界之间(或之上),经度应该落在两个经度边界之间。
因此,您可以简单地根据纬度 top_*_lat
和 bottom_*_lat
中的每一个以及 *_left_long
和 [=14 中的每一个来请求具有匹配边界框的行=] 经度:
lat, long = <latitude>, <longitude>
matching_rows = df.query(
# top and bottom latitudes, top lat > bottom lat, north to south
"top_left_lat >= @lat >= bottom_right_lat and "
# left and right longitudes, left long < right long, west to east
"top_left_long <= @long <= bottom_right_long"
)
上面的 pandas.DataFrame.query()
expression 只是做了一个简单的几何点包含测试,并假设您的边界框不跨越 anti-meridian(国际日期变更线)也不与任何一极重叠。
您必须对输入数据框中的每个位置执行此操作; Pandas 无法基于任意表达式合并数据帧(目前)。您可以按两个坐标之一对输入进行分组,以生成与该坐标匹配的行子集,然后在每个组的第二个坐标上进一步过滤它们。
如果您的输入数据帧也非常大,那么使用数据库进行这样的连接可能会更好。