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

如何基于0.005米距离聚合Pandas中经纬度关联的Val列均值

解决按0.005米地理范围迭代聚合的问题

你提到的需求没办法直接用pandas.Grouper实现,因为它是基于固定分组规则,而你的需求是动态迭代分组——以当前未处理的第一个点为基准,圈定0.005米范围的所有点聚合,再跳到范围外的下一个点重复操作。下面是具体的实现步骤和代码:

步骤说明

  • 首先实现经纬度坐标的距离计算(这里用Haversine公式,适合短距离的精确计算);
  • 迭代遍历数据:每次取当前未处理的第一个点作为基准,筛选出所有距离它≤0.005米的记录;
  • 对筛选出的记录计算Val的均值、记录数,用基准点的坐标作为分组标识(也可以选择用该组的平均坐标,按需调整);
  • 跳过已处理的记录,重复直到所有数据都被聚合。

完整代码实现

import pandas as pd
import numpy as np

# 定义Haversine距离计算函数(单位:米)
def haversine(lat1, lon1, lat2, lon2):
    R = 6371000  # 地球半径,单位米
    phi1 = np.radians(lat1)
    phi2 = np.radians(lat2)
    delta_phi = np.radians(lat2 - lat1)
    delta_lambda = np.radians(lon2 - lon1)
    
    a = np.sin(delta_phi/2)**2 + np.cos(phi1)*np.cos(phi2)*np.sin(delta_lambda/2)**2
    c = 2*np.arctan2(np.sqrt(a), np.sqrt(1-a))
    
    return R * c

# 构造你的示例DataFrame
data = {
    'Time': ['19:24:50.925', '19:24:51.022', '19:24:51.118', '19:24:51.215', '19:24:51.312',
             '19:24:51.409', '19:24:51.506', '19:24:51.603', '19:24:51.699', '19:24:51.796',
             '19:24:51.892', '19:24:51.990', '19:24:52.087', '19:24:52.183', '19:24:52.281',
             '19:24:52.378', '19:24:52.474', '19:24:52.571', '19:24:52.668'],
    'Lat': [35.61068333, 35.61068333, 35.61068333, 35.61068394, 35.61068455,
            35.61068515, 35.61068576, 35.61068636, 35.61068697, 35.61068758,
            35.61068818, 35.61068879, 35.61068939, 35.61069042, 35.61069083,
            35.61069125, 35.61069222, 35.61069278, 35.61069333],
    'Long': [139.6304283]*19,
    'Val': [-54.6, -52.9, -52.6, -52.2, -49.3, -52.1, -52.2, -51.3, -51.8, -52.6,
            -53.5, -51.8, -54.1, -51.8, -53.5, -55.6, -53.2, -50.8, -54]
}
df = pd.DataFrame(data)

# 初始化结果列表和当前起始索引
result = []
current_idx = 0
total_rows = len(df)

while current_idx < total_rows:
    # 取当前基准点的坐标
    base_lat = df.iloc[current_idx]['Lat']
    base_lon = df.iloc[current_idx]['Long']
    
    # 计算所有未处理行到基准点的距离
    distances = haversine(base_lat, base_lon, df['Lat'][current_idx:], df['Long'][current_idx:])
    
    # 筛选距离≤0.005米的行的索引(相对于未处理的子DataFrame)
    mask = distances <= 0.005
    group_indices = mask[mask].index
    
    # 获取对应的原DataFrame的行范围
    start = current_idx
    end = current_idx + len(group_indices)
    
    # 提取分组数据
    group_df = df.iloc[start:end]
    
    # 计算聚合值:用基准点的坐标,Val均值,记录数
    agg_result = {
        'Lat': base_lat,
        'Long': base_lon,
        'Val_mean': group_df['Val'].mean(),
        'Count_of_records': len(group_df)
    }
    
    result.append(agg_result)
    
    # 更新当前起始索引到分组的下一行
    current_idx = end

# 转换为结果DataFrame
result_df = pd.DataFrame(result)
print(result_df)

代码细节说明

  • Haversine函数:精确计算经纬度两点间的球面距离,单位转换为米,完全匹配你0.005米的范围要求;
  • 迭代逻辑:严格遵循你描述的“从第一个位置为基准,范围外的下一个位置重复”的规则,不会出现重复或遗漏的记录;
  • 聚合自定义:如果需要用分组的平均坐标代替基准点坐标,只需要把base_lat换成group_df['Lat'].mean(),base_lon同理即可。

性能提示

如果你的数据量非常大,这种迭代方式效率可能稍低,此时可以考虑引入空间索引库(比如rtree)来加速距离筛选;但对于中小规模的数据,上面的代码足够高效且易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:57:48