在数据清洗过程中,主要处理的是缺失值,异常值和重复值。所谓清洗,是对数据进行丢弃,填充,替换,去重等操作,实现去除异常,纠正错误,补足缺失的目的。
1. 数据列缺失的4种处理方法
数据缺失分为2种:
- 行记录的缺失,这种情况又称为数据记录丢失;
- 数据列值的丢失,即由于各种原因导致的数据记录种某些列的值缺失。
这里重点讨论数据列类型缺失值的处理,通常有4种处理思路:
- 丢弃
- 补全
相对于丢弃而言,补全是更加常用的缺失值处理方式,常用的补全方法有:- 统计法:对于数值行的数据,使用均值,加权均值,中位数等方法补足;对于分类型数据,使用类别众数最多的值补足。
- 模型法
- 专家补全法
- 其他方法
- 真值转换法
- 不处理
在数据预处理阶段,对于具有缺失值的数据记录不做处理,也是一种思路。这种思路主要看后期的数据分析和建模应用,很多模型对于缺失值有容忍度或灵活的处理方法,因此在预处理阶段可以不做处理。常见的能自动处理缺失值的模型如下:- 忽略,缺失值不参与距离计算,例如KNN;
- 将缺失值作为分布的一种状态,并参与到建模过程,例如各种决策树及其变体;
- 不基于距离做计算,因此基于值的距离做计算,本身的影响就消除,例如DBSCAN。
2. 不要清洗抛弃异常数据
2.1 异常值正常反映了业务运营结果
2.2 异常检测模型
2.3 包容异常值的数据建模
3. 数据重复需要去重吗
以下几种情况,请慎重(不建议)执行数据去重。
- 重复的记录用于分析演变规则
- 重复的记录用于样本不均衡处理
- 重复的记录用于检测业务规则问题
1. 缺失值处理
import pandas as pd # 导入Pandas库
import numpy as np # 导入Numpy库
from sklearn.preprocessing import Imputer # 导入sklearn.preprocessing中的Imputer库
# 生成缺失数据
df = pd.DataFrame(np.random.randn(6, 4), columns=['col1','col2','col3','col4']) # 生成一份数据
df.iloc[1, 1] = np.nan #增加缺失值
df.iloc[4, 3] = np.nan
print(df)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 NaN 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 NaN
5 0.615499 0.138902 -0.523084 -0.608018
# 查看哪些值缺失
nan_all = df.isnull() # 获取所有数据框中的N值
print(nan_all) # 打印输出
col1 col2 col3 col4
0 False False False False
1 False True False False
2 False False False False
3 False False False False
4 False False False True
5 False False False False
# 获得含有NA的列
nan_col = df.isnull().any() # 查找含有至少1个缺失值的列,any()方法用来返回指定轴中的任何元素为True
print("获得含有NA的列")
print(nan_col)
获得含有NA的列
col1 False
col2 True
col3 False
col4 True
dtype: bool
# 获得全部为NA的列
nan_col2 = df.isnull().all() # 查找全部缺失值的列,其中all()方法用来返回指定轴的所有元素都为True
print("获取全部为NA的列")
print(nan_col2)
获取全部为NA的列
col1 False
col2 False
col3 False
col4 False
dtype: bool
1.1丢弃缺失值
df2 = df.dropna() # 直接丢弃含有NA的行记录
print(df2)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
5 0.615499 0.138902 -0.523084 -0.608018
1.2 补全缺失值
1.2.1 使用sklearn将缺失值替换为特定值
使用Sklearn的数据预处理方法对缺失值进行处理,首先通过创建Imputer方法创建一个预处理对象,参数说明如下:
- strategy: 为默认缺失值的字符串,默认为NaN,strategy的值可以是mean(均值),median(中位数),most_frequent;
- axis: 用来设置输入的轴,默认值为0,即使用列做计算逻辑。
nan_model = Imputer(missing_values='NaN', strategy='mean', axis=0) # 建立替换规则:将值为Nan的缺失值用均值做替换
nan_result = nan_model.fit_transform(df) # 应用模型规则
print(nan_result)
[[-1.00285617 -0.07899506 -0.60695655 -1.62471244]
[ 0.04468906 -0.15452215 1.39967806 1.34189211]
[-0.25801157 -0.34136463 0.12636506 -2.01033919]
[-0.76607272 0.03276415 0.03368498 -0.68469122]
[ 0.38592178 -0.52391692 1.2277487 -0.7171737 ]
[ 0.61549888 0.13890169 -0.5230837 -0.60801774]]
1.2.2 使用Pandas将缺失值替换为特定值
Pandas对缺失值的处理方法是df.fillna(),该方法中最主要的两个参数是:value和method。前者通过固定的值(或手动指定)替换缺失值,后者通过使用Pandas提供的默认方法替换缺失值,以下是methods支持的方法:
- pad和ffill:使用前面的值替换缺失值
- backfill和bfill:使用后面的值替换缺失值
# 用后面的值替换缺失值
nan_result_pd1 = df.fillna(method='backfill')
print(nan_result_pd1)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 -0.341365 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 -0.608018
5 0.615499 0.138902 -0.523084 -0.608018
# 用后面的值替换缺失值,限制每列只能替换一个缺失值
nan_result_pd2 = df.fillna(method='bfill', limit=1)
print(nan_result_pd2)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 -0.341365 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 -0.608018
5 0.615499 0.138902 -0.523084 -0.608018
# 用前面的值替换缺失值
nan_result_pd3 = df.fillna(method='pad')
print(nan_result_pd3)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 -0.078995 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 -0.684691
5 0.615499 0.138902 -0.523084 -0.608018
# 用0替换缺失值
nan_result_pd4 = df.fillna(0)
print(nan_result_pd4)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 0.000000 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 0.000000
5 0.615499 0.138902 -0.523084 -0.608018
# 用不同值替换不同列的缺失值
nan_result_pd5 = df.fillna({ 'col2':1.1, 'col4':1.4})
print(nan_result_pd5)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 1.100000 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 1.400000
5 0.615499 0.138902 -0.523084 -0.608018
# 用平均数代替,选择各自列的均值替换缺失值
nan_result_pd6 = df.fillna(df.mean()['col2':'col4'])
print(nan_result_pd6)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 -0.154522 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 -0.717174
5 0.615499 0.138902 -0.523084 -0.608018
# 使用replace方法替换缺失值
nan_result_pd7 = df.replace(np.nan, 0)
print(nan_result_pd7)
col1 col2 col3 col4
0 -1.002856 -0.078995 -0.606957 -1.624712
1 0.044689 0.000000 1.399678 1.341892
2 -0.258012 -0.341365 0.126365 -2.010339
3 -0.766073 0.032764 0.033685 -0.684691
4 0.385922 -0.523917 1.227749 0.000000
5 0.615499 0.138902 -0.523084 -0.608018
2. 异常值处理
有关异常值的确定有很多规则和方法,这里使用Z标准化得到的阈值作为判断标准,当标准化后的得分超过阈值则为异常。
import pandas as pd # 导入Pandas库
#生成异常数据
df = pd.DataFrame({ 'col1':[1, 120, 3, 5, 2, 12, 13], 'col2':[12, 17, 31, 53, 22, 32, 43]})
print(df)
col1 col2
0 1 12
1 120 17
2 3 31
3 5 53
4 2 22
5 12 32
6 13 43
2.1 通过Z-Score方法判断异常值
df_zscore = df.copy() # 复制一个用来存储Z-Score得分的数据框
cols = df.columns # 获得数据框的列名
print(cols)
for col in cols: # 循环读取每列
df_col = df[col] # 得到每列的值
z_score = (df_col - df_col.mean()) / df_col.std() # 计算每列的z-score得分
df_zscore[col] = z_score.abs() > 2.2 # 判断Z-Score得分是否大于2.2,如果是则为True,否则则为False
print(df_zscore)
Index(['col1', 'col2'], dtype='object')
col1 col2
0 False False
1 True False
2 False False
3 False False
4 False False
5 False False
6 False False
上述示例中,阈值的设定是确定异常与否的关键,通常当阈值大于2时,已经是相对异常的表现值。
 在判断异常值主要考虑的关键点是: 如 何 判 断 异 常 值 \color{red}{如何判断异常值} 如何判断异常值 。对于有固定业务规则的可以直接套用业务规则,而对于没有固定业务规则的,可以采用常见的数据模型进行判断,即基于概率分布的模型(例如正态分布的标准差范围),基于聚类的方法(例如KMeans),基于密度的方法(例如LOF),基于分类的方法(KNN),基于统计的方法(例如分位数法)等,此时异常值的定义带有较强的主观判断色彩,具体需要根据实际情况选择。
3. 重复值处理
import pandas as pd
# 生成重复数据
data1 = ['a', 3]
data2 = ['b', 2]
data3 = ['a', 3]
data4 = ['c', 2]
df = pd.DataFrame([data1, data2, data3, data4], columns=['col1','col2'])
print(df)
col1 col2
0 a 3
1 b 2
2 a 3
3 c 2
3.1 判断重复数据
isDuplicated = df.duplicated() # 判断重复数据记录
print(isDuplicated)
0 False
1 False
2 True
3 False
dtype: bool
3.2 删除重复值
3.2.1 删除数据记录中所有列值相同的记录
new_df1 = df.drop_duplicates() # 删除数据记录中所有列值相同的记录
print(new_df1)
col1 col2
0 a 3
1 b 2
3 c 2
3.2.2 删除数据记录中col1值相同的记录
new_df2 = df.drop_duplicates(['col1'])
print(new_df2)
col1 col2
0 a 3
1 b 2
3 c 2
3.2.3 删除数据记录中col2值相同的记录
new_df3 = df.drop_duplicates(['col2'])
print(new_df3)
col1 col2
0 a 3
1 b 2
3.2.4 删除数据记录中指定列(col1/col2)值相同的记录
new_df4 = df.drop_duplicates(['col1','col2'])
print(new_df4)
col1 col2
0 a 3
1 b 2
3 c 2
4. 技术点总结
- 通过pd.DataFrame新建数据框;
- 通过df.iloc[]来选择特定的列或对象;
- 使用Pandas的isnull()判断值是否为空;
- 使用all()和any()判断每列是否包含至少1个为True或者全部为True的情况;
- 使用Pandas的dropna()直接删除缺失值。
- 使用Sklearn.preprocessing中的Imputer方法对缺失值进行填充和替换,支持3种填充方法:mean(均值),median(中位数),most_frequent(众数);
- 使用Pandas的fillna填充缺失值,支持更多自定义的值和常用预定义法;
- 通过copy获取一个对象副本,常用于原始对象和复制对象同时进行操作的场景;
- 通过for循环遍历可迭代的列表值。
- 自定义Z-Score计算公式;
- 通过Pandas的duplicated()判断重复数据记录;
- 通过Pandas的drop_duplicates()删除重复记录,可指定特定的列或全部。