如何将最近的线关联到 Python 中的每个给定点?
How to associate closest line to every given point in Python?
我有两个 Pandas DataFrame,第一个名为 Points,列为 'longitude' 和 '纬度'(即地理坐标);并且,第二个数据框被命名为 Links,其中包含以下列:'lon1' & 'lat1'对于第一个点,'lon2' & 'lat2' 对于第二个点,那么每一行中给出的每对点都会创建一个 link/line.此外,对于 Links DataFrame,它有一个名为“link_id”的列。
假设,大约有 10 个点和 4,000 个链接。我如何通过返回 'link_id' 并将其作为名为 'closest_link' 的附加列附加到点数据帧?
这是一种可能有效的方法。考虑:
- 在两个数据帧 Points 和 Links 和 ,
之间生成叉积
- 然后将函数应用到新 DataFrame 中的每个 行。
- 找出函数为每个组报告的最小距离。
让我们调用新的 df,PointsLinks。
下面是一些采用这种方法的代码:
import pandas as pd
import random
Points = pd.DataFrame( [ [ 1,2 ], [ 3,4 ], [ 5,6 ] ], columns = [ 'longitude', 'latitude' ] )
Links = pd.DataFrame( [ [ 'Link1', ( 4,3 ) , ( -1, -2 ) ], [ 'Link2', (10,10) , ( -5, -5 ) ] ], columns = [ 'linkid', 'lon1&lat1', 'lon2&lat2' ] )
print(Points)
print(Links)
#Step 1:
def cartesian_product_basic(left, right):
return (
left.assign(key=1).merge(right.assign(key=1), on='key').drop('key', 1))
def DistanceToLink( pointlink ):
return random.randrange(10)
PointsLinks = cartesian_product_basic(Points,Links)
print( PointsLinks )
#Step 2:
PointsLinks['distance'] = PointsLinks.apply( lambda row : DistanceToLink(row), axis = 'columns' )
print( PointsLinks )
#Step 3: Find the smallest distance per group
closest = PointsLinks.sort_values( [ 'latitude', 'longitude', 'distance' ] , ascending = True ).groupby( [ 'latitude', 'longitude'] ).head(1)
# Drop the unnecessary columns
closest.drop( columns = ['lon1&lat1','lon2&lat2','distance'] , inplace=True)
print(closest)
这是代码创建的数据帧:
积分:
longitude latitude
0 1 2
1 3 4
2 5 6
链接:
linkid lon1&lat1 lon2&lat2
0 Link1 (4, 3) (-1, -2)
1 Link2 (10, 10) (-5, -5)
然后是 PointsLinks(在使用 apply():
添加距离列之后
longitude latitude linkid lon1&lat1 lon2&lat2 distance
0 1 2 Link1 (4, 3) (-1, -2) 1
1 1 2 Link2 (10, 10) (-5, -5) 6
2 3 4 Link1 (4, 3) (-1, -2) 0
3 3 4 Link2 (10, 10) (-5, -5) 9
4 5 6 Link1 (4, 3) (-1, -2) 5
5 5 6 Link2 (10, 10) (-5, -5) 1
我没有实现 DistanceToLink
。我只是在那里放了一个随机数生成器。这是第一个 pointlink
对象的样子(它是一个代表一行的系列):
longitude 1
latitude 2
linkid Link1
lon1&lat1 (4, 3)
lon2&lat2 (-1, -2)
既然你已经有了每个组合的距离,你可以找到,select,具有最短距离的 PointLink 对(使用 ):
closest = PointsLinks.sort_values( [ 'latitude', 'longitude', 'distance' ] , ascending = True ).groupby( [ 'latitude', 'longitude'] ).head(1)
结果如下:
longitude latitude linkid
0 1 2 Link1
2 3 4 Link1
5 5 6 Link2
我有两个 Pandas DataFrame,第一个名为 Points,列为 'longitude' 和 '纬度'(即地理坐标);并且,第二个数据框被命名为 Links,其中包含以下列:'lon1' & 'lat1'对于第一个点,'lon2' & 'lat2' 对于第二个点,那么每一行中给出的每对点都会创建一个 link/line.此外,对于 Links DataFrame,它有一个名为“link_id”的列。
假设,大约有 10 个点和 4,000 个链接。我如何通过返回 'link_id' 并将其作为名为 'closest_link' 的附加列附加到点数据帧?
这是一种可能有效的方法。考虑:
- 在两个数据帧 Points 和 Links 和 , 之间生成叉积
- 然后将函数应用到新 DataFrame 中的每个 行。
- 找出函数为每个组报告的最小距离。
让我们调用新的 df,PointsLinks。
下面是一些采用这种方法的代码:
import pandas as pd
import random
Points = pd.DataFrame( [ [ 1,2 ], [ 3,4 ], [ 5,6 ] ], columns = [ 'longitude', 'latitude' ] )
Links = pd.DataFrame( [ [ 'Link1', ( 4,3 ) , ( -1, -2 ) ], [ 'Link2', (10,10) , ( -5, -5 ) ] ], columns = [ 'linkid', 'lon1&lat1', 'lon2&lat2' ] )
print(Points)
print(Links)
#Step 1:
def cartesian_product_basic(left, right):
return (
left.assign(key=1).merge(right.assign(key=1), on='key').drop('key', 1))
def DistanceToLink( pointlink ):
return random.randrange(10)
PointsLinks = cartesian_product_basic(Points,Links)
print( PointsLinks )
#Step 2:
PointsLinks['distance'] = PointsLinks.apply( lambda row : DistanceToLink(row), axis = 'columns' )
print( PointsLinks )
#Step 3: Find the smallest distance per group
closest = PointsLinks.sort_values( [ 'latitude', 'longitude', 'distance' ] , ascending = True ).groupby( [ 'latitude', 'longitude'] ).head(1)
# Drop the unnecessary columns
closest.drop( columns = ['lon1&lat1','lon2&lat2','distance'] , inplace=True)
print(closest)
这是代码创建的数据帧:
积分:
longitude latitude
0 1 2
1 3 4
2 5 6
链接:
linkid lon1&lat1 lon2&lat2
0 Link1 (4, 3) (-1, -2)
1 Link2 (10, 10) (-5, -5)
然后是 PointsLinks(在使用 apply():
添加距离列之后 longitude latitude linkid lon1&lat1 lon2&lat2 distance
0 1 2 Link1 (4, 3) (-1, -2) 1
1 1 2 Link2 (10, 10) (-5, -5) 6
2 3 4 Link1 (4, 3) (-1, -2) 0
3 3 4 Link2 (10, 10) (-5, -5) 9
4 5 6 Link1 (4, 3) (-1, -2) 5
5 5 6 Link2 (10, 10) (-5, -5) 1
我没有实现 DistanceToLink
。我只是在那里放了一个随机数生成器。这是第一个 pointlink
对象的样子(它是一个代表一行的系列):
longitude 1
latitude 2
linkid Link1
lon1&lat1 (4, 3)
lon2&lat2 (-1, -2)
既然你已经有了每个组合的距离,你可以找到,select,具有最短距离的 PointLink 对(使用
closest = PointsLinks.sort_values( [ 'latitude', 'longitude', 'distance' ] , ascending = True ).groupby( [ 'latitude', 'longitude'] ).head(1)
结果如下:
longitude latitude linkid
0 1 2 Link1
2 3 4 Link1
5 5 6 Link2