机器学习——数据清洗

发布时间:2023年12月18日

【说明】文章内容来自《机器学习入门——基于sklearn》,用于学习记录。若有争议联系删除。???

1、数据清洗简介

????????在处理数据之前,需要进行数据质量分析,了解数据的功能和作用,检查原始数据中是否存在脏数据。脏数据一般是指不符合要求以及不能直接进行相应分析的数据。

????????脏数据往往存在如下问题:没有列头,一个列有多个参数,列数据的单位不统一,存在缺失值、空行、重复数据和非ASCII字符,有些列头应该是数据而不应该是列名参数等等。可将这些问题大致归类为缺失值、异常值和重复值等噪声数据问题。

2、清洗方法

2.1 缺失值

????????缺失值通常是指记录的缺失和记录中某个字段信息的缺失,一般以空白、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)

2.2 异常值

异常值指录入错误以及不合理的数据,一般采用箱形图和标准差,两种办法进行识别。

2.2.1 采用箱形图识别,异常值用中位数填充。
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())

【说明】该代码需要接前面代码内容。

2.2.2 采用标准差识别异常值

当数据服从正态分布时,异常值被定义为一组测定值中与平均值的偏差超过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())

【说明】该代码需要接前面代码内容。

2.2.3 通过z-score 法判断异常值
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)

2.3 重复值

消除重复数据的算法主要有优先队列算法、近邻排序算法和多趟近邻排序法。

2.3.1 pandas数据清洗函数
  • df.duplicated:判断各行是否重复,False为非重复值。
  • df.drop_duplicates:删除重复行。
  • df.fillna(num):用实数num填充缺失值。
  • df.dropna:删除 DataFrame 数据中的缺失值,即删除NaN数据。其语法为DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

【参数说明】

  1. axis:0为行,1为列
  2. how:any表示删除带有NaN的行,all表示删除全为NaN的行
  3. thresh:取值为int型,保留至少指定个非NaN行
  4. subset:取值为list型, 在特定列处理缺失值
  5. inplace:True表示修改原文件,false表示不修改原文件
  • del df['col1']:直接删除某列。
  • df.drop([ ]'col1',···],axis=1):删除指定列,也可以删除指定行,
  • df.rename(index={'row1': 'A'},columns = {'col1': 'B'}):重命名索引名和列名。
  • df.replace():替换 DataFrame,可以用字典表示,例如{'1': 'A','2:'B'},
  • df[ ].map(function):对指定列进行函数转换。map是 Series 中的函数。
  • pd.merge(df1,df2,on='col1', how= 'inner', sort= True):合并两个DataFrame,按照共有的列作内连接(交集),outer为外连接(并集),对结果排序。
  • df1.combine_first(df2):用df2的数据补充dl的缺失值。

(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)
文章来源:https://blog.csdn.net/qq_41566819/article/details/134971283
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。