PyKrige插值保存为CSV时经纬度数值超出范围如何排查
错误原因
你的代码有几个核心问题,直接导致经纬度数值异常:
- 多余的投影转换操作:你在
generate_grid函数里调用了basemap对经纬度网格做投影,原始单位为「度」、范围在[-180,180]/[-90,90]的地理坐标,经过投影后会变成单位为「米」的平面坐标,数值自然会变成百万级,这是投影后的正常结果,不是插值计算出错。你参考的示例里加basemap转换是为了后续绘图用,不是克里金插值的必须步骤。 - 导出时取错了坐标字段:你在
inter_todf函数里用的grid['x']、grid['y']就是刚才提到的投影后米制坐标,根本不是原始的经纬度值,而且你还把坐标和经纬度的对应关系搞反了。 - 额外的代码疏漏:没有导入pandas库;导出CSV时未加参数,会额外写入无用的行索引。
修复方法
如果只需要输出「纬度、经度、插值数值」结构的CSV,不需要做地图投影绘图,直接删掉basemap相关的投影逻辑,导出时取原始经纬度网格即可,修复后的完整代码如下:
import numpy as np import pandas as pd from pykrige.ok import OrdinaryKriging def get_data(df): return { "lons": np.array([6.47, 4.8, 1.94]), "lats": np.array([46.37, 43.9, 47.83]), "values": np.array([-29.5, -27.6, -32.5]), } def extend_data(data): return { "lons": np.concatenate([np.array([lon-360 for lon in data["lons"]]), data["lons"], np.array([lon+360 for lon in data["lons"]])]), "lats": np.concatenate([data["lats"], data["lats"], data["lats"]]), "values": np.concatenate([data["values"], data["values"], data["values"]]), } def generate_grid(data, delta=1): # 移除basemap投影逻辑,直接生成经纬度网格 grid_lon = np.arange(-180, 180, delta) grid_lat = np.arange(np.amin(data["lats"]), np.amax(data["lats"]), delta) lon_grid, lat_grid = np.meshgrid(grid_lon, grid_lat) return { "lon": grid_lon, "lat": grid_lat, "lon_grid": lon_grid, "lat_grid": lat_grid } def interpolate(data, grid): Ok = OrdinaryKriging( data["lons"], data["lats"], data["values"], variogram_model='exponential', ) return Ok.execute("grid", grid["lon"], grid["lat"]) def inter_todf(interpolation, grid): dfl = pd.DataFrame({ # 直接读取原始经纬度网格,不使用投影后的坐标 'Lat': grid['lat_grid'].reshape(-1), 'Long': grid['lon_grid'].reshape(-1), 'Value': interpolation.reshape(-1) }) return dfl base_data = get_data() # 生成网格时不再传入basemap参数 grid = generate_grid(base_data, 1) extended_data = extend_data(base_data) interpolation, interpolation_error = interpolate(extended_data, grid) dfl = inter_todf(interpolation, grid) # 导出时加index=False避免写入多余行索引 dfl.to_csv('interp_result.csv', index=False)
运行修复后的代码,输出的DataFrame里Lat范围会落在4348、Long范围落在-180180,完全符合地理坐标的取值规则。
如果你确实需要保留basemap投影做后续绘图,不需要删除投影逻辑,只要在导出CSV的时候单独用原始经纬度网格生成对应列即可,不要把投影后的米制坐标当做经纬度写入文件。
内容的提问来源于stack exchange,提问作者Weiss
相关产品推荐
相关产品推荐

