应用目标
-
手动准备异常数据集(使用新手学习最广泛地数据集iris.csv,自行添加异常值和空值) -
识别异常数据(方法一:3σ原则识别异常值 方法二:箱形图) -
填补缺失值/空白值(向上填补、向下填补、指定值填补) -
数据清洗结果保存至文件
思路分析
main函数
-
为了更好地封装功能函数,采用统一的接口,功能函数返回相同的数据结构。 -
相较于以往,可插入性更加完善,比如方便添加若干种异常值处理方法或数据填充方法。 -
main函数完成的是框架工作,提供统一接口,方便后期扩充功能函数。
def main():
path = "iris_mistake.csv"
or_data = read_data(path)
outlier_method = input('输入异常值处理方法(three_sigma/box_plot):')
if outlier_method == "three_sigma":
outlier = three_sigma(or_data)
elif outlier_method == "box_plot":
outlier = box_plot(or_data)
nan_data = update_data_to_null(or_data, outlier)
fill_method = input('输入空值填补方法(fillup/filldown/value):')
fill_data = fillna(nan_data,fill_method)
new_path = "iris_" + outlier_method + "_" + fill_method + ".csv"
write_csv(new_path,fill_data)
if __name__=="__main__":
main()
异常值处理功能函数
3σ原则
- 以列为单位进行循环处理(计算均值方差 -> 找到上下界 -> 返回异常值的index元组)
- 不同的数据集,需要手动调整pass的列(iris数据集的最后一列Species 不需要参与计算)
def three_sigma(or_data):
column_id = 0
outlier = []
for column_head in or_data.columns:
if column_head == 'Species':
pass
else:
print(column_head)
column_data_sum = or_data[column_head].sum()
column_data_mean = or_data[column_head].mean()
column_data_std = or_data[column_head].std()
print("总和:",end=' ')
print(column_data_sum)
print("均值:", end=' ')
print(column_data_mean)
print("方差:", end=' ')
print(column_data_std)
high = column_data_mean + 3 * column_data_std
low = column_data_mean - 3* column_data_std
for cell in or_data[column_head]:
if cell > high or cell < low :
print("异常值:",end=' ')
print(cell)
row_id = or_data[(or_data[column_head]==cell)].index.tolist()
for i in row_id:
cell_iloc = (i, column_id)
outlier.append(cell_iloc)
column_id = column_id + 1
print(outlier)
return outlier
箱形图
- 总体功能与上一种方法如出一辙,最大的不同点在于绘制箱形图,具体的参数设置已经在注释标明,更官方的plot资料参考其他优质博客。
def box_plot(or_data):
column_id = 0
outlier = []
for column_head in or_data.columns:
if column_head == 'Species':
pass
else:
iqr = or_data[column_head].quantile(0.75) - or_data[column_head].quantile(0.25)
val_low = or_data[column_head].quantile(0.25) - iqr * 1.5
val_up = or_data[column_head].quantile(0.75) + iqr * 1.5
print(column_head)
print("IQR:", end=" ")
print(iqr)
print("下阈值:", end=" ")
print(val_low)
print("上阈值:", end=" ")
print(val_up)
for cell in or_data[column_head]:
if cell > val_up or cell < val_low:
print("异常值:", end=' ')
print(cell)
row_id = or_data[(or_data[column_head] == cell)].index.tolist()
for i in row_id:
cell_iloc = (i, column_id)
outlier.append(cell_iloc)
column_id = column_id + 1
print(outlier)
show_data = or_data.iloc[:, 0:4]
fig, axes = plt.subplots(1, 4)
color = dict(boxes='DarkGreen', whiskers='DarkOrange',
medians='DarkBlue', caps='Red')
show_data.plot(kind='box', ax=axes, subplots=True,
title='Different boxplots', color=color, sym='r+')
fig.subplots_adjust(wspace=1, hspace=1)
fig.savefig('boxplot.png')
return outlier
异常值置空+ 空值填充功能函数
异常值置空
def update_data_to_null(or_data,outlier):
for loc in outlier:
or_data.iloc[loc[0], loc[1]] = np.nan
print(or_data.iloc[loc[0],loc[1]])
return or_data
空值填充
def fillna(nan_data,fill_method):
if fill_method == "fillup":
return nan_data.fillna(method='ffill')
elif fill_method == "filldown":
return nan_data.fillna(method='bfill')
else:
somevalue = float(input("输入填充的数值:"))
return nan_data.fillna(value=somevalue)
读写csv文件功能函数
读csv文件
def read_data(path):
data = pd.read_csv(path)
print(type(data))
return data
写csv文件
def write_csv(new_path,fill_data):
fill_data.to_csv(path_or_buf=new_path , header=True, index =False)
运行结果
采用不同的功能函数得到不同的结果
源码分享
此次源码暂且不提交github或gitee,关注博主,联系邮箱 Andel2001@163.com
|