关于数据的批量回归插补缺失值
缺失值是数据分析工作中常见的数据问题,我们通常通过中位数、众数、平均数等进行缺失值插补,对于需要高精度插补的水文气象等数据,我们经常使用回归的方式插补,但是,利用excel回归插补需要耗费大量的经历,尤其站点较多的情况下,更是让人头疼,利用python,可以快速方便的进行数据的回归插补。
数据形式
数据的形式大体为上图,站点有100多个,年份是51到18年,可见数据量之大,当然站点缺测也很多,需要我们补充成完整序列。
整理思路
- 读取数据
- 找到完整的无缺失值数据
- 分别做无缺失数据与缺失数据的相关系数
- 拿出相关性较好的数据做插补
代码实现
1.读取数据
- 首先导入需要的包。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import interpolate
from sklearn.linear_model import LinearRegression
matplotlib和seaborn是画图用的,不出图可以省略,scipy主要做差值,与回归做一个比较。
- 读取数据
data = pd.read_excel("chabu.xlsx")
利用pandas的read_excel函数可以读取excel数据。结果如下,缺失值较多:
- 把0值填充为缺失值
我的数据中0值即为缺失值,所以需要进行0值的替换填充,如果数据不是这样可忽略这一操作。
index = data.index
clo = data.columns
data = np.where(data == 0 , np.NAN , data)
new_data = pd.DataFrame(data=data , index=index,columns=clo)
用index取到data的索引,即年份,用columns取到标签,即站点号。利用numpy的where函数把data中的0值替换为缺失值,因为返回值为numpy数组,所以新建一个DataFrame,把年份和站点标签加入即为整理好的数据。
2.找到完整的无缺失值数据
完整无缺失的数据是插补的主要依据,所以需要找出来。
a = new_data.isnull().any()
print(a[a == False])
full_data = new_data[[53446,53463,54218]]
chabu = new_data.drop([53446,53463,54218],axis=1)
首先,new_data.isnull().any()可以看到缺失值的情况,返回值为布尔值,True为有缺失值,False为无缺失值,打印出a[a == False],即为完整的无缺失值数据标签。
从结果中可以看出,53446、53463、54218这三个站点为完整数据序列。把完整序列拿出来,在原序列中删除。
3.分别做无缺失数据与缺失数据的相关系数
做回归需要找到相关系数较高的数据进行回归分析。
cor1 = pd.concat((full_data[53446],chabu),axis=1).corr()
high_corr = cor1[53446][cor1[53446] > 0.5].index
high_corr = high_corr .drop(53446)
首先构造第一个完整数据与缺失数据的相关系数,利用corr可以计算出相关系数矩阵,然后取出cor1[53446]这一列(表示所有数据与53446的相关系数),把大于0.5的index(相当于取出相关系数大于0.5的站点号)取出来,最后,把53446删掉。
上图为high_corr的输出结果,储存了相关性较高的站点号。
4.拿出相关性较好的数据做插补
high_corr储存了相关性较高的站点号,只要拿出来做插补即可。
- scipy库
一开始我用scipy库进行插补,scipy库里的interpolate可以很好的进行数据的差值。
class scipy.interpolate.interp1d(x,y,kind ='linear',axis = -1,copy = True,bounds_error = None,fill_value = nan )
interp1d为1为内插函数,kind可以选择差值的方式,如线性、曲面、样条函数等,注,这里的线性差值不是我们所谓的回归插补,线性差值是一种数值计算的概念,通过线性进行无限的逼近某一个值,相当于把给定的每两个点之间连直线,然后利用这条直线把落在这两个点取值范围之间的值推算出来,如果给到的预测值不在x的范围中,可以通过**fill_value=“extrapolate”**参数来进行外延求解。下面给出示例。
zuhe = pd.concat