如何改进While循环实现Sklearn最近邻坐标遍历与去重?
问题分析与改进方案
原循环的核心问题
new_example一直用loc当经纬度值,根本没读取数据集里的实际坐标,完全没达到遍历目标for i in df是遍历DataFrame的列名,不是遍历行,逻辑完全错了- 每次循环直接覆盖结果变量,没累积生成完整路径
- 完全没做「过滤已识别位置」的逻辑
改进后的实现代码
from sklearn.neighbors import NearestNeighbors import pandas as pd # 初始化最近邻模型(注意haversine要求坐标是弧度制,必须先转换) nn = NearestNeighbors(metric="haversine") # 把经纬度转成弧度后再拟合模型 df[['lat_rad', 'long_rad']] = df[['lat', 'long']].apply(pd.to_numeric).apply(lambda x: x * 3.1415926 / 180) nn.fit(df[["lat_rad", "long_rad"]]) # 初始化路径列表、已访问点的索引集合 route = [] visited = set() # 从第一个点开始遍历(也可以自己指定起始点) current_idx = 0 # 循环直到所有点都被访问过 while len(visited) < len(df): # 标记当前点为已访问 visited.add(current_idx) route.append(df.iloc[current_idx]) # 获取当前点的弧度坐标 current_point = df[["lat_rad", "long_rad"]].iloc[[current_idx]] # 搜索所有点的最近邻(数量设为总点数,确保能找到未访问的) distances, indices = nn.kneighbors(current_point, n_neighbors=len(df)) # 找到第一个没被访问过的最近邻,作为下一个目标点 for idx in indices[0]: if idx not in visited: current_idx = idx break # 把路径转成DataFrame,同时过滤重复位置(基于经纬度去重) route_df = pd.DataFrame(route).drop_duplicates(subset=['lat', 'long'], keep='first') # 输出最终路径 print(route_df)
关键改进点说明
- 弧度转换:
haversine距离公式要求输入是弧度制坐标,不转换的话距离计算完全错误 - 正确遍历逻辑:通过追踪当前点索引,循环寻找未访问的最近邻,逐步生成完整路径
- 已访问过滤:用集合
visited记录已经处理过的点索引,避免重复访问 - 路径累积:用列表
route逐步添加每个点,最后合并成DataFrame - 去重处理:通过
drop_duplicates根据经纬度过滤掉重复的位置
内容的提问来源于stack exchange,提问作者Milo
相关产品推荐
相关产品推荐

