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

基于经纬度点最小距离为DataFrame分配聚类标签的实现问询

解决方法:为df2的点分配最近邻对应的clust标签

我来帮你搞定这个问题——你不需要手动逐个循环计算,我们可以用向量化运算或者专门的最近邻工具来高效完成,同时精准分配对应的聚类标签。下面给你两种实用的方案,分别适合不同的数据规模:

方法1:使用Scipy的cdist计算全量距离(适合中小规模数据)

这种方法直接计算df2每个点与df1所有点的距离,然后找到最小距离对应的clust值。

步骤示例:

首先我们先还原你的示例数据:

import pandas as pd
from scipy.spatial.distance import cdist

# 构造df1
df1 = pd.DataFrame({
    'clust': [1, 1, 2, 2, 3, 3],
    'longitude': [77.62279999, 77.62517676, 77.62753442, 77.62753442, 77.62217671, 77.62217671],
    'latitude': [12.95248389, 12.95027966, 12.93745478, 12.93745478, 12.93353553, 12.93353553]
})

# 构造示例df2
df2 = pd.DataFrame({
    'longitude': [77.623, 77.627, 77.622],
    'latitude': [12.951, 12.937, 12.934]
})

接下来执行标签分配:

# 提取df1的坐标矩阵
df1_coords = df1[['longitude', 'latitude']].values
# 提取df1的clust标签
df1_clust = df1['clust'].values

# 计算df2与df1所有点的欧氏距离矩阵(shape: [df2行数, df1行数])
distance_matrix = cdist(df2[['longitude', 'latitude']].values, df1_coords, metric='euclidean')

# 找到每个df2点对应的最小距离的索引
min_dist_indices = distance_matrix.argmin(axis=1)

# 根据索引匹配对应的clust标签,添加到df2中
df2['assigned_clust'] = df1_clust[min_dist_indices]

运行后df2就会新增assigned_clust列,每个点都对应了df1中最近点的聚类标签。

方法2:使用Sklearn的NearestNeighbors(适合大规模数据)

如果你的df1和df2数据量很大,全量计算距离会非常耗时,这时候用NearestNeighbors的KD-Tree/Ball-Tree算法会高效很多,它会优化最近邻的搜索过程。

步骤示例:

import pandas as pd
from sklearn.neighbors import NearestNeighbors

# 同样先构造示例数据(和上面一致)
df1 = pd.DataFrame({
    'clust': [1, 1, 2, 2, 3, 3],
    'longitude': [77.62279999, 77.62517676, 77.62753442, 77.62753442, 77.62217671, 77.62217671],
    'latitude': [12.95248389, 12.95027966, 12.93745478, 12.93745478, 12.93353553, 12.93353553]
})

df2 = pd.DataFrame({
    'longitude': [77.623, 77.627, 77.622],
    'latitude': [12.951, 12.937, 12.934]
})

# 初始化最近邻模型,只找最近的1个点
nn_model = NearestNeighbors(n_neighbors=1, metric='euclidean')
# 用df1的坐标训练模型
nn_model.fit(df1[['longitude', 'latitude']].values)

# 查找df2每个点的最近邻索引
distances, indices = nn_model.kneighbors(df2[['longitude', 'latitude']].values)

# 匹配clust标签,注意indices是二维数组,需要flatten成一维
df2['assigned_clust'] = df1['clust'].iloc[indices.flatten()].values

这个方法在数据量较大时,速度会比cdist快很多,而且代码同样简洁。

补充说明:

  • 两种方法默认用的是欧氏距离,如果你的坐标是经纬度,需要计算球面距离的话,可以把metric参数改成'haversine',但要注意把经纬度转换成弧度(用np.radians()),因为haversine距离的输入要求是弧度制的坐标。
  • 如果df1中有重复点(比如你示例里clust2和3的重复点),这不影响结果,因为最近邻的索引会指向其中一个,对应的clust标签是一致的。

内容的提问来源于stack exchange,提问作者muni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:06:12