python 採用pandas的DataFrame實現對數字型別用均值填補和分類型別用眾數填補

Renlijuande發表於2020-12-10

今天在用python對資料的數字型別用均值填補,分類型別用眾數填補,遇到幾個坑,mark一下:
1.眾數需要一列一列的填補
2.DataFrame的mode()函式會返回一個series,即多個數需要從中選擇一個進行填補,不然會一直填補不上。(我這裡是隨機選擇一個)

原始碼如下

"""
採用均值和眾數將缺失值填補
dataset是list
columns_classification是list,分類型別的位置
"""
def impute_data_by_mean_or_mode(dataset,columns_classification):
    full_dataset=np.copy(dataset)
    full_dataset=pd.DataFrame(full_dataset)
#    print(full_dataset)
    #將資料分為數字型別和分類型別
    classification_data=full_dataset[columns_classification]
    number_dataset=full_dataset.drop(full_dataset.columns[columns_classification], axis=1)#刪除多列的方法
    #先用均值填補數字型別的欄位
    number_imputed_data=number_dataset.fillna(np.mean(number_dataset))
    #眾數需要一列一列填補
    flag=0#標記是否第一次
    classification_imputed_data=pd.DataFrame()
    for index, columns in classification_data.iteritems():#按列迴圈
        mode_list=columns.mode().to_list()#可能存在多個眾數,這也是總容易犯錯的地方
#        print(mode_list)
        #隨機選一個眾數
        random_val=random.randint(0,len(mode_list)-1)
        random_mode=mode_list[random_val]
        
        #將眾數填入
        columns=columns.fillna(random_mode)
        columns=pd.DataFrame(columns)
#        print(columns) # 輸出列名
        #拼接分類型別資料
        if flag==0:
            classification_imputed_data=columns
        else:
            classification_imputed_data=classification_imputed_data.join(columns)
        flag+=1

#    print(classification_imputed_data)
    #將填補好的資料合併
    imputed_data=number_imputed_data.join(classification_imputed_data)
    #根據索引將資料恢復原來的順序
    imputed_data=imputed_data.sort_index(axis=1)#預設為升序
    
#    print("--------插補結果----------")
#    print(imputed_data)
    return imputed_data

if __name__=='__main__':
    #定義一個陣列
    dataset=[[1,2.222,3,4,5],[2,None,None,None,5],[None,None,3,4,None],[1,2.5661,3,4,5.234]]
    impute_data_by_mean_or_mode(dataset,[0,2,3])

執行結果如下:
在這裡插入圖片描述

相關文章