今天在用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])
运行结果如下: