Python Geopandas:像循环图一样对点样本进行排序

Python Geopandas:像循环图一样对点样本进行排序,python,sorting,pandas,geopandas,Python,Sorting,Pandas,Geopandas,我正在尝试geopandas来处理一些点数据。我的最终GeoDataFrame在此处表示: 为了使用OSM数据计算两点之间的最短道路,我必须对我的点进行排序 如果不是,下一个Python模块将计算最短路径,但不一定是最近点之间的最短路径。主要问题是旅行的限制 如果我的点仅在一条直线上,则每个点的纬度和经度的基本排序函数就足够了,如: df1 = pd.read_csv("file.csv", sep = ",") df1 = df1.sort_values(['Latitude','Longi

我正在尝试geopandas来处理一些点数据。我的最终GeoDataFrame在此处表示:

为了使用OSM数据计算两点之间的最短道路,我必须对我的点进行排序

如果不是,下一个Python模块将计算最短路径,但不一定是最近点之间的最短路径。主要问题是旅行的限制

如果我的点仅在一条直线上,则每个点的纬度和经度的基本排序函数就足够了,如:

df1 = pd.read_csv("file.csv", sep = ",")
df1 = df1.sort_values(['Latitude','Longitude'], ascending = [1,1]) 
# (I'm starting with pandas df before GeoDataFrame conversion)
如果我们从排序后的前一张图片的“上”点开始,数据帧的第二个点将是最近的点,以此类推。。。在第五点之前,wich位于图片右侧(因此不再是最近的了)


所以我的问题是:有人知道如何实现这种特殊的排序,还是我必须手动更改索引

如果我正确理解你的问题,你想重新排列点的顺序,这样它们就能创建最短的路径

我也遇到了同样的问题。 这是一个接受常规数据框(=每个坐标都有单独的字段)的函数。我相信您可以修改其中一个函数以接受geodataframe,或者修改dataframe以将几何体字段拆分为x和y字段

def autoroute_points_df(points_df, x_col="e",y_col="n"):

    '''
    Function, that converts a list of random points into ordered points, searching for the shortest possible distance between the points.
    Author: Marjan Moderc, 2016
    '''
    points_list = points_df[[x_col,y_col]].values.tolist()

    # arrange points in by ascending Y or X
    points_we = sorted(points_list, key=lambda x: x[0])
    points_sn = sorted(points_list, key=lambda x: x[1])

    # Calculate the general direction of points (North-South or West-East) - In order to decide where to start the path!
    westmost_point = points_we[0]
    eastmost_point = points_we[-1]

    deltay = eastmost_point[1] - westmost_point[1]
    deltax = eastmost_point[0] - westmost_point[0]
    alfa = math.degrees(math.atan2(deltay, deltax))
    azimut = (90 - alfa) % 360

    # If main directon is towards east (45°-135°), take westmost point as starting line.
    if (azimut > 45 and azimut < 135):
        points_list = points_we
    elif azimut > 180:
        raise Exception("Error while computing the azimuth! It cant be bigger then 180 since first point is west and second is east.")
    else:
        points_list = points_sn

    # Create output (ordered df) and populate it with the first one already.
    ordered_points_df = pd.DataFrame(columns=points_df.columns)
    ordered_points_df = ordered_points_df.append(points_df.ix[(points_df[x_col]==points_list[0][0]) & (points_df[y_col]==points_list[0][1])])

    for iteration in range(0, len(points_list) - 1):

        already_ordered = ordered_points_df[[x_col,y_col]].values.tolist()

        current_point = already_ordered[-1]  # current point
        possible_candidates = [i for i in points_list if i not in already_ordered]  # list of candidates

        distance = 10000000000000000000000
        best_candidate = None
        for candidate in possible_candidates:
            current_distance = Point(current_point).distance(Point(candidate))
            if current_distance < distance:
                best_candidate = candidate
                distance = current_distance

        ordered_points_df = ordered_points_df.append(points_df.ix[(points_df[x_col]==best_candidate[0]) & (points_df[y_col]==best_candidate[1])])

    return ordered_points_df
def自动路由点df(点df,x_col=“e”,y_col=“n”):
'''
函数,该函数将随机点列表转换为有序点,搜索点之间可能的最短距离。
作者:Marjan Moderc,2016
'''
points\u list=points\u df[[x\u col,y\u col]].values.tolist()
#按Y或X升序排列点
点=已排序(点列表,键=λx:x[0])
点编号=已排序(点列表,键=λx:x[1])
#计算点的大致方向(南北或东西)-以确定路径的起点!
最西端的点=点[0]
最东点=点[1]
deltay=最东的_点[1]-最西的_点[1]
deltax=最东的_点[0]-最西的_点[0]
阿尔法=数学学位(数学atan2(德尔泰、德尔泰))
方位角=(90-alfa)%360
#如果主方向朝东(45°-135°),则以最西端为起点。
如果(方位角>45且方位角<135):
积分列表=积分
elif方位角>180:
引发异常(“计算方位角时出错!它不能大于180,因为第一个点是西,第二个点是东。”)
其他:
点列表=点编号
#创建输出(有序df)并用第一个输出填充它。
有序点测向=pd.DataFrame(列=点测向列)
有序点测向=有序点测向追加(点测向ix[(点测向[x列]==点测向列表[0][0])和(点测向[y列]==点测向列表[0][1]))
对于范围(0,len(点列表)-1)内的迭代:
已排序=已排序的\u点\u df[[x\u列,y\u列]]值。tolist()
当前点=已订购[-1]#当前点
可能的_候选人=[如果我不在已排序的_名单中,我在积分榜中为i]#候选人名单
距离=100000000000000000000
最佳候选人=无
对于可能的_候选人中的候选人:
当前距离=点(当前点)。距离(点(候选))
如果当前距离<距离:
最佳候选人
距离=当前距离
有序点测向=有序点测向追加(点测向ix[(点测向[x\u列]==最佳候选[0])和(点测向[y\u列]==最佳候选[1]))
返回订购的积分

希望它能解决你的问题!

你说的“像赛马场”是什么意思?对不起,我不太清楚这个词…比如旅游,或者旅行?你指的是a吗?是的,正是这样…我会修改我的问题让它更清楚!@ResMar抱歉打扰你,但还没有人回答,我想知道你是否有实现这个目标的想法…祝你愉快!我想它可以工作。我会尽快测试,我会验证的最重要的是:非常感谢:-)早上好@MarjanModerc!我刚刚用一个“真实”点的样本重新测试了你的算法,但有一个小问题:两点之间最近的路线并不总是绘制全局循环图的最佳方式。我可以给你发一个带有你算法的GeoDF吗?也许会更清楚!提前谢谢,祝你有愉快的一天