数据准备<2>:数据质量检查-实战篇

-回复 -浏览
楼主 2019-10-08 16:57:11
举报 只看此人 收藏本贴 楼主

上一篇文章:《数据质量检查-理论篇》主要介绍了数据质量检查的基本思路与方法,本文作为补充,从实战角度出发,总结一套基于Python的数据质量检查模板。 承接上文,仍然从重复值检查、缺失值检查、数据倾斜检查、异常值检查四方面进行描述。

1.环境介绍

版本:python2.7
工具:Spyder
开发人:hbsygfz

2.数据集介绍

数据集:dataset.xlsx




3.代码实现

3.1 导入相关库

1import pandas as pd


3.2 读取数据集

1dataset = pd.read_excel("/labcenter/python/dataset.xlsx")
2discColList = ['col4','col7']
3contColList = ['col1','col2','col3','col5','col6']


 

3.3 重复值检查

主要统计指标:重复记录数、字段唯一值数。

 1### (1)重复记录数
2def dupRowsCheck(df):
3    dupRows = df.duplicated().sum()
4    return dupRows
5### (2)字段唯一值数
6def uiqColValCheck(df):
7    # 记录数,变量数
8    m,n = df.shape
9    uiqDf = pd.DataFrame(index=df.columns,columns=['rows','uiqCnt'])
10    uiqDf['rows'] = m
11    for j in range(n):
12        ser = df.iloc[:,j]
13        name = df.columns[j]
14        uiqCnt = len(ser.unique())
15        uiqDf.loc[name,'uiqCnt'] = uiqCnt
16    return uiqDf

执行与结果:

 1dupRowsCheck(dataset)
2Out[95]: 0
3uiqColValCheck(dataset)
4Out[96]:
5      rows uiqCnt
6col1    10     10
7col2    10      9
8col3    10     10
9col4    10      3
10col5    10      9
11col6    10      5
12col7    10      2


3.4 缺失值检查

主要统计指标:字段空值记录数。

 1def missingCheck(df):
2    # 记录数,变量数
3    m,n = df.shape
4    rowsSer = pd.Series(index=df.columns)
5    rowsSer.name = 'rows'
6    # 空值记录数
7    nullCntSer = df.isnull().sum()
8    nullCntSer.name = 'nullCnt'
9    # 合并结果
10    missDf = pd.concat([rowsSer,nullCntSer],axis=1)
11    missDf['rows'] = m
12    return missDf

执行与结果:

 1missingCheck(dataset)
2Out[97]:
3      rows  nullCnt
4col1    10        0
5col2    10        1
6col3    10        0
7col4    10        0
8col5    10        1
9col6    10        0
10col7    10        0


3.5 数据倾斜检查

主要统计指标:记录数、类别个数、最大类别记录数、最大类别记录数占比。

 1def skewCheck(df,discList,contList,bins):
2    # 离散型变量类别统计
3    new_df1 = df[discList]
4    skewDf1 = pd.DataFrame(index=discList,columns=['rows','classCnt','mostClassCnt','mostClassRio'])
5    m1,n1 = new_df1.shape
6    for j in range(n1):
7        ser = new_df1.iloc[:,j]
8        name = new_df1.columns[j]
9        freqSer = pd.value_counts(ser)
10        skewDf1.loc[name,'rows'] = m1
11        skewDf1.loc[name,'classCnt'] = len(freqSer)
12        skewDf1.loc[name,'mostClassCnt'] = freqSer[0]
13        skewDf1.loc[name,'mostClassRio'] = freqSer[0] * 1.00 / m1
14    # 连续型变量分箱统计
15    new_df2 = df[contList]
16    skewDf2 = pd.DataFrame(index=contList,columns=['rows','classCnt','mostClassCnt','mostClassRio'])
17    m2,n2 = new_df2.shape
18    for j in range(n2):
19        ser = new_df2.iloc[:,j]
20        name = new_df2.columns[j]
21        freqSer = pd.value_counts(pd.cut(ser,bins))
22        skewDf2.loc[name,'rows'] = m2
23        skewDf2.loc[name,'classCnt'] = len(freqSer)
24        skewDf2.loc[name,'mostClassCnt'] = freqSer[0]
25        skewDf2.loc[name,'mostClassRio'] = freqSer[0] * 1.00 / m2
26    # 合并结果
27    skewDf = pd.concat([skewDf1,skewDf2],axis=0)
28    return skewDf

执行与结果:

 1skewCheck(dataset,discColList,contColList,4)
2Out[98]:
3     rows classCnt mostClassCnt mostClassRio
4col4   10        3            5          0.5
5col7   10        2            6          0.6
6col1   10        4            3          0.3
7col2   10        4            3          0.3
8col3   10        4            4          0.4
9col5   10        4            3          0.3
10col6   10        4            1          0.1


3.6 异常值检查

主要统计指标:最大值、最小值、平均值、标准差、变异系数、大于平均值+3倍标准差的记录数、小于平均值-3倍标准差记录数、大于上四分位+1.5倍的四分位间距记录数、小于下四分位-1.5倍的四分位间距记录数、正值记录数、零值记录数、负值记录数。

 1### (1)异常值统计
2def outCheck(df,contList):
3    new_df = df[contList]
4    resDf = new_df.describe()
5    resDf.loc['cov'] = resDf.loc['std'] / resDf.loc['mean']     #计算变异系数
6    resDf.loc['mean+3std'] = resDf.loc['mean'] + 3 * resDf.loc['std']  #计算平均值+3倍标准差
7    resDf.loc['mean-3std'] = resDf.loc['mean'] - 3 * resDf.loc['std']  #计算平均值-3倍标准差
8    resDf.loc['75%+1.5dist'] = resDf.loc['75%'] + 1.5 * (resDf.loc['75%'] - resDf.loc['25%'])  #计算上四分位+1.5倍的四分位间距
9    resDf.loc['25%-1.5dist'] = resDf.loc['25%'] - 1.5 * (resDf.loc['75%'] - resDf.loc['25%'])  #计算下四分位-1.5倍的四分位间距
10    # 3segma检查
11    segmaSer1 = new_df[new_df > resDf.loc['mean+3std']].count()    #平均值+3倍标准差
12    segmaSer1.name = 'above3SegmaCnt'
13    segmaSer2 = new_df[new_df < resDf.loc['mean-3std']].count()    #平均值-3倍标准差
14    segmaSer2.name = 'below3SegmaCnt'
15    # 箱线图检查
16    boxSer1 = new_df[new_df > resDf.loc['75%+1.5dist']].count()    #上四分位+1.5倍的四分位间距
17    boxSer1.name = 'aboveBoxCnt'
18    boxSer2 = new_df[new_df < resDf.loc['25%-1.5dist']].count()    #下四分位-1.5倍的四分位间距
19    boxSer2.name = 'belowBoxCnt'
20    # 合并结果
21    outTmpDf1 = pd.concat([segmaSer1,segmaSer2,boxSer1,boxSer2],axis=1)
22    outTmpDf2 = resDf.loc[['max','min','mean','std','cov']]
23    outDf = pd.concat([outTmpDf2.T,outTmpDf1],axis=1)
24    return outDf
25### (2)正负分布检查
26def distCheck(df,contList):
27    new_df = df[contList]
28    distDf = pd.DataFrame(index=contList,columns=['rows','posCnt','zeroCnt','negCnt'])
29    m,n = new_df.shape
30    for j in range(n):
31        ser = new_df.iloc[:,j]
32        name = new_df.columns[j]
33        posCnt = ser[ser>0].count()
34        zeroCnt = ser[ser==0].count()
35        negCnt = ser[ser<0].count()
36        distDf.loc[name,'rows'] = m
37        distDf.loc[name,'posCnt'] = posCnt
38        distDf.loc[name,'zeroCnt'] = zeroCnt
39        distDf.loc[name,'negCnt'] = negCnt
40    return distDf

执行与结果:

 1outCheck(dataset,contColList)
2Out[101]:
3           max    min        mean         std       cov  above3SegmaCnt  below3SegmaCnt  aboveBoxCnt  belowBoxCnt
4col1  110.0000  101.0  105.500000    3.027650  0.028698               0               0            0            0
5col2   58.0000   20.0   34.444444   11.959422  0.347209               0               0            1            0
6col3  221.0000   10.0   87.700000   71.030588  0.809927               0               0            0            0
7col5  598.0000    0.0  246.333333  235.303647  0.955225               0               0            0            0
8col6    0.0115   -0.3   -0.027740    0.095759 -3.452026               0               0            2            1
9distCheck(dataset,contColList)
10Out[102]:
11     rows posCnt zeroCnt negCnt
12col1   10     10       0      0
13col2   10      9       0      0
14col3   10     10       0      0
15col5   10      7       2      0
16col6   10      3       6      1





我要推荐
转发到