不能直接用 np.array 存经纬度坐标,因为地理坐标是球面数据,需满足纬度∈[-90,90]、经度∈[-180,180)等约束,NumPy 无自动归一化与校验机制,广播运算易产生非法值。

为什么不能直接用 np.array 存经纬度坐标?
因为地理坐标是球面数据,不是欧氏平面上的普通数值——直接用 np.array 存 [lat, lon] 看似没问题,但一旦做广播运算(比如批量加减偏移、计算距离),会得到错误结果。比如 np.array([89.9, 179.9]) + np.array([0.2, 0.2]) 得到 [90.1, 180.1],这在地理上是非法坐标(纬度超 ±90°,经度超 ±180°),而 NumPy 不会自动归一化或校验。
- 纬度必须落在
[-90.0, 90.0]区间,超出即无效 - 经度通常需归一化到
[-180.0, 180.0)或[0.0, 360.0),否则两点间最短路径判断出错 - 批量计算大圆距离、投影变换时,纯 NumPy 缺少地理语义,容易忽略地球曲率
用 np.where 和 np.mod 快速规整经纬度数组
如果你已有原始坐标数组,想快速修复越界值,别写循环——用向量化操作更稳。
例如把一批经度统一映射到 [-180, 180):
lons = np.array([181.0, -185.0, 365.0]) lons_norm = np.where(lons >= 180.0, lons - 360.0, lons) lons_norm = np.where(lons_norm < -180.0, lons_norm + 360.0, lons_norm)
更简洁写法(但注意浮点精度):
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
lons_norm = (lons + 180) % 360 - 180
-
np.mod对负数处理不如手动np.where可控,比如np.mod(-185, 360)返回175.0,而非期望的-5.0 - 纬度规整必须用
np.clip:lats_clipped = np.clip(lats, -90.0, 90.0),不能用模运算 - 若原始数据含
NaN,np.where会保留它;np.clip同样保持NaN,无需额外处理
配合 scipy.spatial.distance 计算球面距离时的陷阱
NumPy 本身不提供大圆距离函数,常有人误用 scipy.spatial.distance.euclidean 直接算经纬度差——这在赤道附近误差小,但在高纬度地区完全失真(比如赫尔辛基和摩尔曼斯克之间直线距离算出来可能比实际短 40%)。
- 正确做法:先用
np.radians把度转为弧度,再套 Haversine 公式(或用geopy/pyproj) - 如果坚持纯 NumPy + SciPy,可用
scipy.spatial.distance.pdist配合自定义 metric,但必须传入弧度且实现球面距离逻辑 - 常见错误:忘记单位转换,输入仍是度数,导致
np.sin(np.deg2rad(lat))写成np.sin(lat),结果全错
用 np.meshgrid 生成规则地理网格时要注意什么?
做栅格分析(如插值、热力图底图)时,常用 np.meshgrid 构建经纬网,但顺序极易搞反。
正确顺序(符合 GIS 常规):
lats = np.linspace(-90, 90, 181) lons = np.linspace(-180, 180, 361) Lon, Lat = np.meshgrid(lons, lats) # 注意:lons 在前,lats 在后 → shape=(181, 361)
- 输出
Lat是二维数组,Lat[i, j]对应第i行(纬度索引)、第j列(经度索引),符合(y, x)习惯 - 若调换参数顺序,
np.meshgrid(lats, lons)会得到(361, 181)形状,后续 reshape 或绘图(如plt.pcolormesh(Lon, Lat, data))会报错或错位 - 网格分辨率不均等:高纬度区域相同经度差对应的实际距离更短,做面积加权统计时不能直接用
np.diff(lons).mean() * np.diff(lats).mean()
地理坐标的本质是带约束的球面量,NumPy 是工具,不是地理引擎——越早引入 pyproj 或 rioxarray 处理投影与坐标系,后期踩的坑越少。

















