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

基于Pandas的人员邻近位置聚类分组技术问询

问题需求

现有包含latitude、longitude、story字段的Pandas DataFrame,需将其拆分为每组9行的子数据集(chunk),需满足以下要求:

  • 每组中不得包含latitude和longitude完全相同的行(代表同一建筑人员)
  • 组内人员的latitude和longitude需相近(邻近区域),可通过最近邻算法定义邻近关系
  • 最终将所有chunk合并为完整DataFrame

示例数据

# 修正语法错误后的原始数据
data = {
    "latitude": [49.5619579, 49.5619579, 49.5628938, 49.5628938, 49.5630028, 49.5633175, 49.56397639999999, 49.5659508, 49.566359, 49.56643220000001, 49.56643220000001, 49.5672061, 49.567729, 49.5677449, 49.5679685, 49.5679685, 49.568089, 49.5686342, 49.5687609, 49.5688543, 49.5690616, 49.5695834, 49.5706579, 49.5711228, 49.5713705, 49.5716422, 49.5717749],
    "longitude": [10.9995758, 10.9995758, 11.000319, 11.000319, 10.9990996, 10.9993819, 11.004145, 10.9873409, 11.0003023, 10.9999593, 10.9999593, 10.9935709, 11.0011213, 10.9954016, 10.9982288, 10.9982288, 10.9894035, 10.9896749, 10.9887881, 10.9975928, 10.9931367, 10.9851579, 10.9853273, 10.9912959, 10.9939141, 10.9910182, 10.9867083],
    "story": [2.0, 4.0, 3.0, 4.0, 1.0, 2.0, 3.0, 1.0, 3.0, 1.0, 5.0, 1.0, 1.0, 1.0, 1.0, 5.0, 5.0, 1.0, 3.0, 2.0, 3.0, 2.0, 2.0, 4.0, 4.0, 5.0, 5.0]
}

数据集前9行示例

MasterKitchen_Latitude  MasterKitchen_Longitude MasterKitchen_Story
0   49.561958               10.999576                 2.0
1   49.561958               10.999576                 4.0
2   49.562894               11.000319                 3.0
3   49.562894               11.000319                 4.0
4   49.563003               10.999100                 1.0
5   49.563317               10.999382                 2.0
6   49.563976               11.004145                 3.0
7   49.565951               10.987341                 1.0
8   49.566359               11.000302                 3.0

讨论阶段代码

df = pd.DataFrame(data)

# 创建合并经纬度的字符串列
df["lat_long"] = df["latitude"].astype(str) + "_" + df["longitude"].astype(str)

# 按合并列分组
grouped_df = df.groupby("lat_long")

print(grouped_df.mean())
解决方案

以下是满足需求的完整实现步骤:

1. 预处理:标记唯一人员

为每个唯一的经纬度组合分配ID,区分不同建筑人员,同时保留所有原始行数据:

import pandas as pd
import numpy as np
from sklearn.neighbors import NearestNeighbors

# 加载数据
df = pd.DataFrame(data)

# 生成人员ID:每个经纬度组合对应唯一ID
df['person_id'] = df.groupby(['latitude', 'longitude']).ngroup()

2. 提取唯一人员的坐标集合

创建仅包含唯一人员经纬度的数据集,用于后续最近邻计算:

# 提取唯一人员的信息
unique_persons = df[['person_id', 'latitude', 'longitude']].drop_duplicates().reset_index(drop=True)
# 转换为numpy数组,用于模型输入
coords = unique_persons[['latitude', 'longitude']].values

3. 基于最近邻构建分组

使用Haversine距离(适用于经纬度坐标的距离计算)的K近邻算法,构建符合要求的chunk:

# 初始化K近邻模型,设置每组最多9个人员
nn = NearestNeighbors(n_neighbors=9, metric='haversine')
# 经纬度需转换为弧度后输入模型
nn.fit(np.radians(coords))

chunks = []
# 记录已分配到chunk的人员ID,避免重复分配
assigned_persons = set()

# 遍历每个唯一人员,构建邻近分组
for idx in range(len(unique_persons)):
    current_person_id = unique_persons.loc[idx, 'person_id']
    if current_person_id in assigned_persons:
        continue
    
    # 获取当前人员的9个最近邻(包含自身)
    _, neighbor_indices = nn.kneighbors([np.radians(coords[idx])])
    # 提取邻近人员的ID
    neighbor_person_ids = unique_persons.loc[neighbor_indices[0], 'person_id'].tolist()
    # 过滤掉已分配的人员
    available_ids = [pid for pid in neighbor_person_ids if pid not in assigned_persons]
    
    # 选取最多9个可用人员,生成当前chunk
    selected_ids = available_ids[:9]
    chunk = df[df['person_id'].isin(selected_ids)]
    chunks.append(chunk)
    
    # 更新已分配人员集合
    assigned_persons.update(selected_ids)

# 处理剩余未分配的人员(不足9个的情况)
remaining_ids = [pid for pid in unique_persons['person_id'] if pid not in assigned_persons]
if remaining_ids:
    chunks.append(df[df['person_id'].isin(remaining_ids)])

# 合并所有chunk,得到最终的完整DataFrame
final_df = pd.concat(chunks, ignore_index=True)

4. 验证分组有效性

可以通过以下代码检查每个chunk是否符合“无重复经纬度行”的要求:

for i, chunk in enumerate(chunks, 1):
    duplicate_count = chunk.duplicated(subset=['latitude', 'longitude']).sum()
    print(f"Chunk {i}: 重复经纬度行数 = {duplicate_count}, 总行数 = {len(chunk)}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:45:00