如何用5近邻非NaN值的均值填充地理数据集的缺失值?
如何用5近邻非NaN值的均值填充地理数据集的缺失值?
看起来你已经迈出了正确的第一步,但用lag_spatial处理缺失值确实会踩坑——这个函数默认不会过滤邻居里的NaN值,而且如果目标点本身是NaN,计算结果也还是NaN。咱们换个更直接的思路:针对每个带NaN的点,手动筛选出它的5个近邻里的有效(非NaN)值,再计算均值填充,这样就靠谱多了。
下面是具体的实现步骤,完全基于你正在用的工具链:
第一步:提取坐标并构建KNN索引
首先把数据里的地理坐标提取成数组,用来构建KNN邻居索引:
import numpy as np from libpysal.weights import KNN # 从geometry列提取所有点的(x,y)坐标数组 coords = np.array(predictions_gdf.geometry.apply(lambda g: (g.x, g.y)).tolist()) # 构建k=5的KNN权重对象 w_knn = KNN(coords, k=5)
第二步:定义填充函数
接下来写一个自定义函数,专门处理每个缺失值的填充逻辑:
def fill_missing_with_neighbor_mean(row): # 如果当前值不是NaN,直接返回原值 if not np.isnan(row['PPM_P']): return row['PPM_P'] # 获取当前行的索引 current_idx = row.name # 拿到该点的5个近邻的索引列表 neighbor_indices = w_knn.neighbors[current_idx] # 提取这些邻居的PPM_P值,并且过滤掉其中的NaN valid_neighbor_values = predictions_gdf.loc[neighbor_indices, 'PPM_P'].dropna() # 返回有效邻居的均值(你说至少有一个非NaN,所以不用处理空值的情况) return valid_neighbor_values.mean()
第三步:应用函数填充缺失值
最后把这个函数应用到整个数据集上,生成填充后的列:
# 生成填充后的新列,也可以直接覆盖原列(根据你的需求来) predictions_gdf['PPM_P_filled'] = predictions_gdf.apply(fill_missing_with_neighbor_mean, axis=1)
为什么之前的方法不行?
你之前用的lag_spatial是计算空间滞后项的工具,它的逻辑是直接对邻居值做加权平均(行归一化后就是简单均值),但它不会自动过滤邻居里的NaN,也不会处理目标点本身是NaN的情况——只要邻居里有NaN,或者目标点是NaN,结果就会是NaN,这就是你遇到问题的原因。而咱们手动筛选有效邻居的方式,能精准避开NaN的干扰。
备注:内容来源于stack exchange,提问作者julieb
相关产品推荐
相关产品推荐

