数据缺失值填充—KNN估计

运行环境
python3.6
jupyter notebook

一、基本思想

先将数据标准化,然后对缺失值的数据点做k邻近填充,计算含缺失值的数据点与其他不含缺失值的数据点的距离矩阵,选出欧氏距离最近的k个数据点。
用选中的k个近邻的数据点对应的字段均值来填充数据中的空缺值。

二、步骤

1.导入数据

import pandas as pd
data = pd.read_csv('iris-带空格数据.csv')
data['id'] = [i for i in range(0,150)]		#加入id列

2.查看空缺值

index = [] #存放空缺值的位置
for i in data.columns:
    a=data[data[i] == ' '].index.tolist()
    index.append(a)
index#一共有七列数据,空缺值在第5列,第三行

输出结果为:[[], [], [], [], [2], [], []]

3.取出要分析的数据

data.iloc[2,4] = 0 #将空值变为0
new_data = data.iloc[:,1:4]#计算空缺值只需要前三列数据

4.计算平均值

#平均值
avg =[]#用来存放平均值
for i in new_data.columns:#遍历dataframe列名
    a = new_data[i].values.tolist()#取出每一列的数据,转成列表
    sum = 0
    for i in range(0,len(a)):
        sum = sum + float(a[i])#求每一列数据之和
    avg.append(sum/len(a))#求平均
avg

结果为:[1.199333333333334, 3.7580000000000027, 3.057333333333334]

5.计算标准差

#标准差
all_value=[]
for i in new_data.columns:
    a = new_data[i].values.tolist()#每一列的数据转成列表
all_value.append(a)#每一列的列表加入到all_value
biaozhuncha = []
for i in range(0,new_data.shape[1]):#一共三列,所以遍历三次。
    sum = 0
    for j in all_value[i]:
        sum = sum + ((float(j)-avg[j])*(float(j)-avg[j]))#计算每一列数据减去对应列的平均值的平方之和
    b = (sum/new_data.shape[0]) ** 0.5#计算每一列数据的标准差
    biaozhuncha.append(b)#把标准差加入到biaozhuncha列表中
biaozhuncha

在这里插入图片描述

6.规范化

#z_score规范化
result = []
for i in range(0,new_data.shape[1]):#遍历三次,因为有三列数据
    z_score=[]
    for j in all_value[i]:#all_value列表,就是上面用到了存放所有列数据的二维列表
        c = (float(j)-avg[i])/biaozhuncha[i]#计算出某一列规范化后的结果
        z_score.append(c)#结果保存在z_score列表中
result.append(z_score)#把三列的结果汇总
new_data['Petal_width'] = result[0]#接着,把规范化得到的结果替换new_data中的值
new_data['Petal_length'] = result[1]
new_data['Sepal_width'] = result[2]

7.计算欧几里得距离

value_result=[]
for i in new_data.columns:
    lie_value = []
    for j in new_data[i].values.tolist():
        lie_value.append(j)
    value_result.append(lie_value)
#此处,将上面得到的规范化结果保存成二位列表,方便后面的计算
d_list=[]
for i in range(0,new_data.shape[0]):
    d = 0
    for j in range(0,new_data.shape[1]):
        d = d+((new_data.iloc[i,j]-new_data.iloc[2,j])*(new_data.iloc[i,j]-new_data.iloc[2,j]))
    d_list.append(d**0.5) result = d_list
df = pd.DataFrame(d_list)#将结果转成dataframe方便我排序。

8.最优解

all_data_result = []
for i in range(3,20):
    all_data=[]
    for j in df.drop(2).sort_values(by=0).head(i).index:
        all_data.append(data.iloc[j,4])
    #print(all_data)
all_data_result.append(all_data)
b_list = []
for i in range(len(all_data_result)):
    sum = 0
    for j in all_data_result[i]:
        sum = sum + float(j)
    b = sum/len(all_data_result[i])
b_list.append(b)

在这里插入图片描述

9.画图

对3到50的预测结果进行可视化。
import matplotlib.pyplot as plt
%matplotlib inline
#把图插在网页里
plt.plot([i for i in range(3,50)],b_list)
在这里插入图片描述

总结

本次实验学习到了很多关于dataframe的操作,有一些对于列表的操作我不是很熟练,但是我可以把列表转成dataframe类型在进行操作。此外,我也很少调用一些对数据计算的函数,让我更加了解到计算平均、标准差和欧几里得距离的方法。对于k-means的算法也有了一定的认识,可以使用一些基本的方法来预测数据并填充空缺值。
数据和源码:链接:https://pan.baidu.com/s/1TPwte04gxkk0Rmna6BQ6iw
提取码:1025

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐