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

Python按100米半径分组经纬度统计:四舍五入到3位小数可行吗?

问题

我有大量带经纬度的地点数据,想要按100米半径范围对这些经纬度进行分组,并统计每个组内的总数。参考GIS相关资料中十进制度数的说明,经纬度小数位数对应不同的覆盖半径,现在想确认:

  1. 将经纬度四舍五入到3位小数,是否能实现100米半径的分组需求?
  2. 我写的Python Pandas示例代码是否能保证分组的准确性,不会损失过多精度?

原始数据表格:

id  lat         long         total
1   1.5021033   103.6241121  1
2   1.502434    103.6239708  1
3   3.1319197   101.6840589  1

期望分组结果:

lat     long      total
1.502   103.624   2
3.132   101.684   1

示例代码:

# Example of code snippet
import pandas as pd

header = ['id', 'lat', 'long', 'total']
content = [[1,1.5021033,103.6241121,1], [2,1.502434,103.6239708,1], [3,3.1319197,101.6840589,1]]
df = pd.DataFrame(content, columns=header)

df['lat'] = df['lat'].round(decimals = 3)
df['long'] = df['long'].round(decimals = 3)
display(df.drop(columns='id').groupby(by=["lat", "long"]).count())
分析与结论

1. 四舍五入到3位小数无法严格满足100米半径分组

经纬度十进制度数对应距离的大致规律:

  • 纬度方向:1度≈111公里,因此0.001度≈111米
  • 经度方向:距离随纬度变化,赤道处1度≈111公里,0.001度≈111米;越往两极,经度方向的距离越小

将经纬度四舍五入到3位小数,相当于把地球表面划分为**约111米×111米(赤道附近)**的网格。同一个网格内的点,最大距离可能达到对角线长度(≈157米),明显超过100米的要求;同时也会存在实际距离小于100米的点,因落在相邻网格被分到不同组的情况。因此这个方案无法严格保证100米半径内的分组准确性。

2. 示例代码的局限性

你提供的代码确实能实现按3位小数经纬度分组统计,但本质是基于网格的粗分组,无法满足100米半径的精确要求,会出现分组误差。

改进方案

如果需要严格按100米半径分组,建议使用空间聚类算法(比如DBSCAN),结合球面距离计算实现。以下是基于geopandas和sklearn的示例:

import pandas as pd
import geopandas as gpd
from sklearn.cluster import DBSCAN
from shapely.geometry import Point

# 加载数据
header = ['id', 'lat', 'long', 'total']
content = [[1,1.5021033,103.6241121,1], [2,1.502434,103.6239708,1], [3,3.1319197,101.6840589,1]]
df = pd.DataFrame(content, columns=header)

# 转换为GeoDataFrame,使用WGS84坐标系(EPSG:4326)
gdf = gpd.GeoDataFrame(
    df,
    geometry=gpd.points_from_xy(df['long'], df['lat']),
    crs="EPSG:4326"
)

# 转换为以米为单位的投影坐标系(示例数据对应马来西亚区域,选用EPSG:32648,可根据数据位置调整)
gdf = gdf.to_crs("EPSG:32648")

# DBSCAN聚类:eps=100米,min_samples=1表示单个点也作为独立组
dbscan = DBSCAN(eps=100, min_samples=1)
gdf['cluster'] = dbscan.fit_predict(gdf[['geometry.x', 'geometry.y']])

# 统计每个组的总数,组内经纬度取平均值
result = gdf.groupby('cluster').agg(
    lat=('lat', 'mean'),
    long=('long', 'mean'),
    total=('total', 'sum')
).reset_index(drop=True)

print(result)

这个方案通过投影坐标系将经纬度转换为米制坐标,再用DBSCAN按100米半径聚类,能严格满足你的分组需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:37:46