You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何改进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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:05:17