【说明】文章内容来自《机器学习入门——基于sklearn》,用于学习记录。若有争议联系删除。
在处理数据之前,需要进行数据质量分析,了解数据的功能和作用,检查原始数据中是否存在脏数据。脏数据一般是指不符合要求以及不能直接进行相应分析的数据。
脏数据往往存在如下问题:没有列头,一个列有多个参数,列数据的单位不统一,存在缺失值、空行、重复数据和非ASCII字符,有些列头应该是数据而不应该是列名参数等等。可将这些问题大致归类为缺失值、异常值和重复值等噪声数据问题。
缺失值通常是指记录的缺失和记录中某个字段信息的缺失,一般以空白、NaN或其他占位符编码,采用删除法和数据填充进行处理。
删除法:如果某个属性的缺失值过多,可以直接删除整个属性。
数据填充:使用一个全局变量填充缺失值,使用属性的平局值、中间值、最大值、最小值或更为复杂的概率统计函数值填充缺失值。
sklearn中的Imputer类或SimpleImputer类用于处理缺失值。
Imputer语法:
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values = "NaN", strategy = "mean")
【参数说明】
missing_values = np.nan :缺失值是NaN。
strategy = 'mean':用平均值、中位数等填充缺失值。
import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
df = pd.DataFrame([["XXl", 8, "black", "class 1", 22],
["L", np.nan, "gray", "class 2", 20],
["XL", 10, "blue", "class 2", 19],
["M", np.nan, "orange", "class 1", 17],
["M", 110, "green", "class 3", np.nan],
["M", 7, "red", "class 1", 22]])
df.columns = ["size", "price", "color", "class", "boh"]
print(df)
#1.创建Imputer
#imp = SimpleImputer(missing_values = np.nan, strategy = "mean")
imp = SimpleImputer(missing_values = np.nan, strategy = "mean")
#2.使用fit_transform函数完成缺失值填充
df["price"] = imp.fit_transform(df[["price"]])
#df["boh"] = imp.fit_transform(df[["boh"]])
print(df)
异常值指录入错误以及不合理的数据,一般采用箱形图和标准差,两种办法进行识别。
import numpy as np
import pandas as pd
a = df["price"].quantile(0.75)
b = df["price"].quantile(0.25)
c = df["price"]
c[(c>=(a-b) * 1.5 + a)| (c <= b - (a-b) * 1.5)] = np.nan
c.fillna(c.median(), inplace = True)
print(c.describe())
【说明】该代码需要接前面代码内容。
当数据服从正态分布时,异常值被定义为一组测定值中与平均值的偏差超过3倍标准差的值。
import numpy as np
import pandas as pd
a = df["price"].mean() + df["price"].std()*3
b = df["price"].mean() - df["price"].std()*3
c = df["price"]
c[(c >= a) | (c <= b)] = np.nan
c.fillna(c.median(), inplace = True)
print(c.describe())
【说明】该代码需要接前面代码内容。
import pandas as pd
import matplotlib.pyplot as plt
#构建包含异常值的矩阵
df = pd.DataFrame([[1, 12], [120, 17],[3, 31],[5, 53],[2, 22],[12, 32],[13, 43]], columns = ['col1','col2'])
print("数据为:\n", df)
#散点图
plt.scatter(df['col1'], df['col2'])
plt.show()
#通过z-score方法判断异常值,超过阈值为异常值
df_zscore = df.copy() #存储Z-score
cols = df.columns #获得数据框的列名
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 #阈值为2.2,大于该值为True,否则为FALSE
print("异常值为:\n",df_zscore)
df_drop_outlier = df[df_zscore['col1'] == False]#删除异常值所在的记录行
print("处理后的数据为:\n", df_drop_outlier)
消除重复数据的算法主要有优先队列算法、近邻排序算法和多趟近邻排序法。
【参数说明】
(1)重复值处理:
import pandas as pd
#生成异常数据
data1, data2, data3, data4 = ['a', 3],['b', 2],['a', 3],['c',2]
df = pd.DataFrame([data1, data2, data3, data4], columns = ['col1','col2'])
print("数据为:\n",df)
isDuplicated = df.duplicated()#判断各行是否重复,False为非重复值。
print("重复值为:\n",isDuplicated)
print("删除数据记录中所有列值相同的记录:\n", df.drop_duplicates())
print("删除数据记录中col1值相同的记录:\n", df.drop_duplicates(['col1']))
print("删除数据记录中col2值相同的记录:\n", df.drop_duplicates(['col2']))
print("删除数据记录中指定列(col1/col2)值相同的记录:\n", df.drop_duplicates(['col1', 'col2']))
(2)df.fillna(num)示例
from numpy import nan as NaN
import pandas as pd
df1 = pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])
print("df1:\n{}\n".format(df1))
df2 = df1.fillna(100)
print("df2:\n{}\n".format(df2))
(3)df.dropna示例
#df.dropna:删除DataFrame数据中的缺失值,即删除NaN数据语法
#DataFrame.dropna(axis = 0, how ='any', thresh = None, subset = None, inplace = False)
from numpy import nan as NaN
import pandas as pd
df1 = pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])
print("df1:\n{}\n".format(df1))
df2 = df1.dropna()
print("df2:\n{}\n".format(df2))
# df3 = df1.dropna(how = 'all')
# print("df3:\n{}\n".format(df3))
(4)df.replace示例
#df.replace示例 替换DataFrame,可以用字典表示
import pandas as pd
#创建数据集
df = pd.DataFrame(
{'名称':['产品 1','产品 2','产品 3','产品 4','产品 5','产品 6','产品 7','产品 8'],
'数量':['A','0.7','0.8','0.4','0.7','B','0.76','0.28'],
'金额':['0','0.48','0.33','C','0.74','0','0','0.22'],
'合计':['D','0.37','0.28','E','0.57','F','0','0.06'],})
#原DataFrame并没有改变,改变的只是一个副本
print("df:\n{}\n".format(df))
df1 = df.replace('A',0.1)
print("df1:\n{}\n".format(df1))
#只需要替换某个数据的部分内容
df2 = df['名称'].str.replace('产品','product')
print("df2:\n{}\n".format(df2))
#上面修改的内容都是df数据的副本,原始数据不作修改
#如果要改变原数据,应添加常用参数inplace= True,用于替换部分区域
df['合计'].replace({'D': 0.11111, 'F': 0.22222}, inplace = True)
print("df:\n{}\n".format(df))
(5)df[].map示例
#df[].map:对指定列进行函数转换。map是series中的函数
import pandas as pd
import numpy as np
df = pd.DataFrame({'key1': ['a', 'a', 'b','b', 'a'],
'key2': ['one', 'two', 'one','two','one'],
'data1': np.arange(5),#默认从0开始到5(不包括5),步长为1
'data2': np.arange(5,10)})#从5到10步长为1
print('df"\n{}\n'.format(df))
df['data1'] = df['data1'].map(lambda x : '%.3f'%x)#lambda将data1中的数据改为保留小数点后3位
print('df:\n{}\n'.format(df))
(6)pd.merge(df1,df2)示例
#pd.merge(df1,df2,on = 'col1',how = 'inner', sort =True):合并两个DataFrame,
#按照共有的列作为内连接(交集)outer为外连接(并集),对结果排序。
import pandas as pd
left = pd.DataFrame({'key': ['k0','k1','k2','k3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1','B2','B3']})
right = pd.DataFrame({'key':['k0','k1','k2','k3'],
'C':['C0', 'C1', 'C2','C3'],
'D':['D0','D1','D2','D3']})
result = pd.merge(left,right,on = 'key')
#on参数传递的key作为连接键
print('left:\n{}\n'.format(left))
print('right:\{}\n'.format(right))
print('result:\n{}\n'.format(result))
(7)df1.combine_first(df2)示例
#df1.combine_first(df2):用df2的数据补充df1的缺失值
from numpy import nan as NaN
import numpy as np
import pandas as pd
a = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], index = ['f', 'e', 'd', 'c', 'b', 'a'])
b = pd.Series([1, np.nan, 3, 4, 5, np.nan], index = ['f', 'e', 'd', 'c', 'b', 'a'])
print(a)
print(b)
c = b.combine_first(a)
print(c)