本文会讲解如何用knn方法填充DataFrame里面的Nan值
一、填充逻辑
1.拆分样本把所有样本分成两类:
完整样本:该行所有特征无缺失
残缺样本:该行存在至少 1 个 NaN,需要补值
2.计算欧氏距离
距离计算规则(只拿共同有效特征算距离)假设样本 A 有缺失,对比样本 B:只挑选A、B 两行都不为空的那些采样点(列),用这些对应数值计算欧式距离,距离越能代表两条波形整体相似度。
3.选取举例最小的前n_neighbors 个样本作为邻居
筛选近邻对残缺样本,算出它和所有完整样本的距离,取距离最小的前 n_neighbors 个样本作为邻居。
4.加权计算
加权计算填充值(weights='distance')距离越近的邻居权重越高
5.填充数据
逐缺失位置循环填充一行里多个 NaN 不会一次性全填,逐个缺失坐标重复上面步骤,全部补完输出完整数值矩阵。
二、读取数据
import pandas as pd
from sklearn.impute import KNNImputer
file_path = "../附件二(测试集) - 副本.xlsx"
df = pd.read_excel(file_path, sheet_name='测试集')
三、提取波形数据
把列名单独存一个变量,然后用这个变量作为参数传输到df这个DataFrame里面提取数据,再把列名的类型换成'字符串',方便后面模型训练(因为模型KNNImputer要求列为字符串类型)
wave_cols = df.columns[4:]
wave_data = df[wave_cols]
wave_data.columns = wave_data.columns.astype(str)
四、定义KNN模型
imputer = KNNImputer(n_neighbors=5,#填补每个缺失值时,KNN会选取5个最相似的邻居样本。weights='distance'#邻居对填补的贡献按距离的倒数加权
)
五、填充数据
wave_filled = imputer.fit_transform(wave_data
)
六、将数据替换回原表
首先还是深拷贝原数据到变量df_knn,然后把df_knn里面的列换成已经填充好的列
df_knn = df.copy()
df_knn[wave_cols] = wave_filled
# 保存
df_knn.to_excel("KNN填补结果.xlsx",index=False
)
print("完成")
#以上代码是把行当做一个样本,列是采样点,缺失值从行中找相近的列来填补
