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

如何在Python Pandas中计算经纬度点5英里半径内的密度?

计算经纬度位置5英里半径内的地点密度方案

核心数学:球面距离计算

经纬度是球面坐标系下的坐标,不能直接用平面距离公式计算两点距离,常用Haversine公式来计算地球表面两点的球面距离(单位可设为英里)。

公式逻辑:

  1. 先将所有经纬度从角度转换为弧度:弧度 = 角度 × π / 180
  2. 代入Haversine公式计算距离:
a = sin²(Δφ/2) + cosφ₁ × cosφ₂ × sin²(Δλ/2)
c = 2 × atan2(√a, √(1−a))
d = R × c
  • φ:纬度,λ:经度
  • Δφ = φ₂ - φ₁(两点纬度差),Δλ = λ₂ - λ₁(两点经度差)
  • R:地球半径,计算英里的话取3956英里

密度计算实现方法

1. 小数据量场景:直接遍历统计

如果你的地点数据量不大(比如几千条以内),可以直接遍历每个目标点,统计所有其他点中距离≤5英里的数量,这个数量就能直接反映该点附近的密集程度(也可以除以5英里半径的面积≈78.5平方英里,得到单位面积的密度值)。

举个Python实现的简单例子:

import math

def haversine_miles(lat1, lon1, lat2, lon2):
    # 角度转弧度
    lat1_rad = math.radians(lat1)
    lon1_rad = math.radians(lon1)
    lat2_rad = math.radians(lat2)
    lon2_rad = math.radians(lon2)
    
    delta_lat = lat2_rad - lat1_rad
    delta_lon = lon2_rad - lon1_rad
    
    a = math.sin(delta_lat/2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(delta_lon/2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    return 3956 * c  # 返回英里距离

# 计算单个点的密度
def get_density(target_lat, target_lon, all_points, radius=5):
    nearby_count = 0
    for lat, lon in all_points:
        if haversine_miles(target_lat, target_lon, lat, lon) <= radius:
            nearby_count += 1
    return nearby_count - 1  # 减去自身

# 示例用法
all_locations = [(40.7128, -74.0060), (40.7306, -73.9352), ...]  # 你的所有地点经纬度
for lat, lon in all_locations:
    density = get_density(lat, lon, all_locations)
    print(f"位置({lat}, {lon})的5英里内地点数量:{density}")

2. 大数据量场景:避免全量两两对比

如果数据量上万甚至更多,全量两两对比的时间复杂度是O(n²),效率极低。可以用空间索引来优化:

  • 用KD树、R树等空间数据结构,先把所有点的坐标(可转换为平面投影坐标,或直接用球面KD树)建立索引,然后快速查询每个目标点半径内的邻近点,时间复杂度能降到O(n log n)。
  • 如果用数据库存储数据,比如PostgreSQL+PostGIS,可以直接用ST_DWithin函数高效统计:
    SELECT 
        target.id,
        COUNT(other.id) AS nearby_count
    FROM locations target
    LEFT JOIN locations other 
        ON ST_DWithin(ST_SetSRID(ST_MakePoint(target.lon, target.lat), 4326)::geography,
                      ST_SetSRID(ST_MakePoint(other.lon, other.lat), 4326)::geography,
                      8046.72)  -- 5英里=8046.72米
        AND target.id != other.id
    GROUP BY target.id;
    

注意事项

  • 如果你不需要精确的球面距离,也可以用近似的平面距离计算(比如将经纬度按一定比例转换为平面坐标),但高纬度地区误差会变大,建议优先用Haversine公式。
  • 密度值可以根据需求调整:比如用“邻近点数量”直接反映密集程度,或者用“邻近点数量/面积”得到单位面积密度,后者更适合跨区域对比。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:55:42