如何匹配坐标略有差异的Pandas DataFrame/Xarray数据集并计算生物群系人口总和
问题描述
我拥有两个覆盖全球、分辨率为0.5度的数据集:
- 植被分类数据集
biom_df:
biom_df ind lat lon biome 0 83.25 -43.25 0 1 83.25 -42.75 1 2 83.25 -42.25 1 3 83.25 -39.75 0 4 83.25 -38.75 2
- 人口数据集
pop_df:
pop_df ind lat lon pop2020 0 83.6875 -33.5625 0 1 83.6875 -33.4375 0 2 83.6875 -33.3125 0 3 83.6875 -33.1875 0 4 83.6875 -33.0625 0
目标是计算每个生物群系(biome)的总人口总和,但两个数据集的经纬度坐标存在微小差异,尝试过两种方法均未成功:
- 方法一:用xarray转换后尝试最近邻选择,但不知道如何将匹配值合并到数据集
- 方法二:用pandas外连接后填充biome,结果不正确
解决方案
方法一:使用Xarray进行最近邻匹配并聚合
Xarray的sel方法结合method='nearest'可批量匹配坐标,之后直接按biome分组求和:
import xarray as xr import pandas as pd # 转换为xarray数据集,将lat/lon设为索引维度 biom_ds = xr.Dataset.from_dataframe(biom_df).set_index(ind=['lat', 'lon']) pop_ds = xr.Dataset.from_dataframe(pop_df).set_index(ind=['lat', 'lon']) # 为人口数据的每个坐标匹配最近的biome值 matched_biome = biom_ds['biome'].sel(lat=pop_ds.lat, lon=pop_ds.lon, method='nearest') # 将匹配后的biome合并到人口数据集 pop_with_biome = pop_ds.assign(biome=matched_biome) # 转换回DataFrame并按biome分组求和 result = pop_with_biome.to_dataframe().groupby('biome')['pop2020'].sum().reset_index() print(result)
说明
sel(method='nearest')会自动为pop_ds的每个(lat, lon)找到biom_ds中空间距离最近的坐标对应的biome值assign方法直接将匹配结果整合到人口数据集,无需手动插入- 最后通过分组求和得到每个生物群系的总人口
方法二:使用Pandas + KDTree实现高效最近邻匹配
如果更习惯用pandas,可借助scipy的KDTree快速完成空间点匹配:
import pandas as pd from scipy.spatial import KDTree # 提取植被数据的坐标和对应的biome值 biom_coords = biom_df[['lat', 'lon']].values biom_kdtree = KDTree(biom_coords) biome_values = biom_df['biome'].values # 为每个人口点查找最近的植被点索引 _, nearest_indices = biom_kdtree.query(pop_df[['lat', 'lon']].values, k=1) # 为人口数据添加匹配的biome字段 pop_df['biome'] = biome_values[nearest_indices] # 按biome分组计算总人口总和 result = pop_df.groupby('biome')['pop2020'].sum().reset_index() print(result)
说明
- KDTree是高效的空间索引结构,适合处理大规模全球数据集的最近邻查询
- 通过索引映射直接为人口点分配对应的biome值,避免了错误的填充逻辑
- 分组求和步骤简单直接,结果准确
原方法失败原因
- 方法一:你尝试用
biom_ds.loc[ind].lat反向选择坐标,逻辑错误,且缺少将匹配结果合并回数据集的关键步骤 - 方法二:外连接后用
ffill()填充biome是错误的,经纬度的顺序填充不代表空间上的最近邻,会导致biome值被错误分配
内容的提问来源于stack exchange,提问作者GittyN
相关产品推荐
相关产品推荐

