数据清洗(删除重复行、判断并用平均值填补无效值)

150 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情


def get_repeated_label(array_1dim):

    label_1dim=[]

    for k in range(len(array_1dim)-1):

        for i in range(k+1,len(array_1dim),1):

            if array_1dim[k]==array_1dim[i]:

                label_1dim.append(i)

    return np.unique(label_1dim)

 

此函数可以返回一维数组中的重复项索引。其算法解释如下图:

图片.png

上面数组其索引是从0开始的,要想找到所有重复项的索引,必须在一次循环中固定一个数(被比较数),然后所有其他数(比较数)和它一一比较,相同则返回比较数索引。

 

下面我们拿上面的数组为例子,模拟一下我们的算法。

当k=0(对应值是3),也就是说被比较数索引为0,则比较数从从索引1到索引12循环,值等于3的索引位[1,9]

当k=1(对应值是3),也就是说被比较数索引为1,则比较数从从索引2到索引12循环,值等于3的索引位[9]

......

当k=11(对应值是16),也就是说被比较数索引为11,则比较数从从索引12到索引12循环,值等于16的索引位是空。

到这里,k无法进行再次循环,即k in [0,11]。此外,观察上面的陈述,我们不难发现 i in [k+1,12]

 

上面数组的比较结果为[1,9,9,8],因为有重复项,所以再返回结果时使用了unique函数。最终结果如下:

 


ar12=np.array([3,3,2,1,7,10,11,6,7,3,5,16,18])

get_repeated_label(ar12)

array([1, 8, 9])

 

第二个函数实现无效值替换,凡是不是整数或者小数的数组元素均被替换为0,这里之所以可以替换为0,是因为原数据中没有任何0值,即使这些无效值被替换为0值,也不会与原数组中的数值混淆。实际上你可以根据实际情况,选择任何适合的替换值。比如一些对你来说容易记忆的单词。

 


def invalid_value_cleaning(array_variable):

    r,c=np.shape(array_variable)

    for i in range(r):

        for j in range(c):

            if type(array_variable[i,j])==float or type(array_variable[i,j])==int:

对二维数组中的每一个元素的类型进行判断,如果是整数或者小数,我们把其忽略,如果不是,则替换成0

                pass

            else:

                array_variable[i,j]=0

    array_variable[np.isnan(array_variable.astype(np.float64))]=0

空值被识别为浮点数,所以可能存在漏掉的空值

array_variable.astype(np.float64),防止数值类型是整型报错

通过isnan函数数组转换为bool数组,然后放到array_variable的索引位选住所有空值(nan)使其替换为0

    return array_variable

 

第三个函数实现用平均值替换0值,实际是平均值替换无效值,即平均值补值法。

 


def fillup_mean_value(array_parameter):

    i,j=np.shape(array_parameter)

    for index_j in range(j):

在这里使用for循环一般情况下效率高于在第一个if处使用循环

        array_columns_nr=list(np.where(array_parameter==0)[1])

把每一列中的0元素的列索引做成列表传给变量array_columns_nr

        if index_j in array_columns_nr:

            appearance_sum=array_columns_nr.count(index_j)

对列表中与index_j相等的列索引进行计数,等价于确定每列中0的个数

            if appearance_sum>0:

                mean_1=(array_parameter[:,index_j]).sum()/(np.shape(array_parameter)[0])

计算算数平均值,注意分母要减去0元素的个数,也就是说0元素不计算在呢,因为0元素是替换无效值而得。

                bollmatrix_1=array_parameter[:,index_j]==0

                array_parameter[bollmatrix_1,index_j]=mean_1 

花式索引的利用

    return array_parameter

 

第四个函数可以删除重复行

 


def delete_rows(list_variable,array_variable):

    array_medium=np.delete(array_variable,list_variable,0)

    return array_medium

 


import xlrd

name='E:/BaiduNetdiskDownload/python/机器学习资料/数据分析初级/salesdetails.xlsx'

information_1=xlrd.open_workbook(name)

information_2 = information_1.sheet_by_name(u'Sheet1')

dataload_1=[]

nrows = information_2.nrows

for j in range(1,nrows,1):

    dataload_1.append(list(information_2.row_values(j)))

Data_Deal_with=np.array(dataload_1,dtype=np.object) 

使用object类型使所有类型数据都能正常显示

print(Data_Deal_with.shape)

(34, 5)

Data_Deal_with 

时间序列不应该重复(类似id)

array([[20170323.0, 126.0, 229.0, 159.0, 134300.0],

       [20170324.0, 128.0, 175.0, 111.0, 221.0],

       [20170325.0, 117.0, 77.0, 40.0, 171.0],

       [20170326.0, 93.0, 30.0, 28.0, 106.0],

       [20170327.0, 73.0, 46.0, 30.0, 123.0],

       [20170328.0, '¥$#', 28.0, 16.0, 74.0],

       [20170329.0, 46.0, 13.0, 10.0, 50.0],

       [20170330.0, 32.0, 11.0, 19.0, 30.0],

       [20170331.0, 25.0, 70000.0, 11.0, 53.0],

       [20170401.0, 41.0, 10.0, 16.0, 27.0],

       [20170401.0, 41.0, 10.0, 16.0, 27.0],

       [20170402.0, 21.0, 166.0, 66.0, 24.0],

       [20170403.0, 60.0, 67.0, 275.0, 17.0],

       [20170404.0, 74.0, 46.0, 51.0, 18.0],

       [20170405.0, 76.0, 25.0, 42.0, 12.0],

       [20170406.0, 54.0, 32.0, '', 11.0],

       [20170407.0, 186.0, 18.0, 18.0, 97700.0],

       [20170408.0, 121.0, 'sales ist Null', 23.0, 440.0],

       [20170409.0, 83.0, 17.0, 16.0, 107.0],

       [20170410.0, 87.0, 12.0, 15.0, 117.0],

       [20170411.0, 35.0, 16.0, 22.0, 62.0],

       [20170411.0, 35.0, 16.0, 22.0, 62.0],

       [20170412.0, '', 23.0, 15.0, 128.0],

       [20170413.0, 25.0, 17.0, 17.0, ''],

       [20170414.0, 24.0, 27.0, '', 30.0],

       [20170415.0, 13.0, 36.0, 12.0, 65.0],

       [20170415.0, 13.0, 36.0, 12.0, 65.0],

       [20170416.0, 9.0, 45.0, 147.0, 22.0],

       [20170417.0, 14.0, 54.0, 22.0, 22.0],

       [20170418.0, 16.0, 21.0, 4.0, 15.0],

       [20170419.0, 8.0, 13.0, 4.0, 23.0],

       [20170420.0, '%$', 59.0, 32452.0, 11.0],

       [20170421.0, 6.0, 89.0, 4.0, 13.0],

       [20170422.0, 5.0, 76.0, 31.0, 11.0]], dtype=object)

Columns_1=Data_Deal_with[:,0] 

时间序列不应该重复(类似id)

Data_information_12=delete_rows(get_repeated_label(Columns_1),Data_Deal_with)

删除重复行

print(Data_information_12.shape)

(31, 5)

Indormation_after_handling=invalid_value_cleaning(Data_information_12)

无效值替换

DataFormat=fillup_mean_value(Indormation_after_handling) 

补充平均值

DataFormat

array([[20170323.0, 126.0, 229.0, 159.0, 134300.0],

       [20170324.0, 128.0, 175.0, 111.0, 221.0],

       [20170325.0, 117.0, 77.0, 40.0, 171.0],

       [20170326.0, 93.0, 30.0, 28.0, 106.0],

       [20170327.0, 73.0, 46.0, 30.0, 123.0],

       [20170328.0, 57.07142857142857, 28.0, 16.0, 74.0],

       [20170329.0, 46.0, 13.0, 10.0, 50.0],

       [20170330.0, 32.0, 11.0, 19.0, 30.0],

       [20170331.0, 25.0, 70000.0, 11.0, 53.0],

       [20170401.0, 41.0, 10.0, 16.0, 27.0],

       [20170402.0, 21.0, 166.0, 66.0, 24.0],

       [20170403.0, 60.0, 67.0, 275.0, 17.0],

       [20170404.0, 74.0, 46.0, 51.0, 18.0],

       [20170405.0, 76.0, 25.0, 42.0, 12.0],

       [20170406.0, 54.0, 32.0, 1161.2413793103449, 11.0],

       [20170407.0, 186.0, 18.0, 18.0, 97700.0],

       [20170408.0, 121.0, 2382.6, 23.0, 440.0],

       [20170409.0, 83.0, 17.0, 16.0, 107.0],

       [20170410.0, 87.0, 12.0, 15.0, 117.0],

       [20170411.0, 35.0, 16.0, 22.0, 62.0],

       [20170412.0, 57.07142857142857, 23.0, 15.0, 128.0],

       [20170413.0, 25.0, 17.0, 17.0, 7800.1],

       [20170414.0, 24.0, 27.0, 1161.2413793103449, 30.0],

       [20170415.0, 13.0, 36.0, 12.0, 65.0],

       [20170416.0, 9.0, 45.0, 147.0, 22.0],

       [20170417.0, 14.0, 54.0, 22.0, 22.0],

       [20170418.0, 16.0, 21.0, 4.0, 15.0],

       [20170419.0, 8.0, 13.0, 4.0, 23.0],

       [20170420.0, 57.07142857142857, 59.0, 32452.0, 11.0],

       [20170421.0, 6.0, 89.0, 4.0, 13.0],

       [20170422.0, 5.0, 76.0, 31.0, 11.0]], dtype=object)

 

因为数据中不应出现小数,往下有两种处理方式


 DataFormat.astype(np.int32)

array([[20170323,      126,      229,      159,   134300],

     [20170324,      128,      175,      111,      221],

     [20170325,      117,       77,       40,      171],

     [20170326,       93,       30,       28,      106],

     [20170327,       73,       46,       30,      123],

     [20170328,       57,       28,       16,       74],

     [20170329,       46,       13,       10,       50],

     [20170330,       32,       11,       19,       30],

     [20170331,       25,    70000,       11,       53],

     [20170401,       41,       10,       16,       27],

     [20170402,       21,      166,       66,       24],

     [20170403,       60,       67,      275,       17],

     [20170404,       74,       46,       51,       18],

     [20170405,       76,       25,       42,       12],

     [20170406,       54,       32,     1161,       11],

     [20170407,      186,       18,       18,    97700],

     [20170408,      121,     2382,       23,      440],

     [20170409,       83,       17,       16,      107],

     [20170410,       87,       12,       15,      117],

     [20170411,       35,       16,       22,       62],

     [20170412,       57,       23,       15,      128],

     [20170413,       25,       17,       17,     7800],

     [20170414,       24,       27,     1161,       30],

     [20170415,       13,       36,       12,       65],

     [20170416,        9,       45,      147,       22],

     [20170417,       14,       54,       22,       22],

     [20170418,       16,       21,        4,       15],

     [20170419,        8,       13,        4,       23],

     [20170420,       57,       59,    32452,       11],

     [20170421,        6,       89,        4,       13],

     [20170422,        5,       76,       31,       11]])

或者


import pandas as pd

Format_DataFrame=pd.DataFrame(DataFormat)

Format_DataFrame

图片.png


format_array_Frame=lambda x:'%u'%x 

整形(格式化)函数构成

Format_DataFrame.applymap(format_array_Frame)

通过applymap函数把format_array_Frame应用到数据框中的每个元素进行格式化。

图片.png