题记:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。

无论,数据分析,数据挖掘,还是算法工程师,工作中80%的时间都用来处理数据,给数据打标签了。而工作中拿到的数据脏的厉害,必须经过处理才能放入模型中。

以下是一脏数据表:(表格放在最后供看官下载练习)

这张表格有多少处数据问题?大家对数据问题是如何定义的?不妨带着疑问阅读下文;

数据处理四性“完全合一”。

完整性:单条数据是否存在空值,统计的字段是否完善。

全面性:观察某一列的全部数值,比如在 Excel 表中,我们选中一列,可以看到该列的平均值、最大值、最小值。我们可以通过常识来判断该列是否有问题,比如:数据定义、单位标识、数值本身。

合法性:数据的类型、内容、大小的合法性。比如数据中存在非 ASCII 字符,性别存在了未知,年龄超过了 150 岁等。

唯一性:数据是否存在重复记录,因为数据通常来自不同渠道的汇总,重复的情况是常见的

数据质量完整性问题:

在介绍数据清洗之前,先学会用python导入数据:

# encoding=utf-8
import pandas as pd
import numpy as np

df = pd.read_csv("C://Users//baihua//Desktop//ceshi.csv",encoding='utf-8') #这里要注意,如果文件中有中文,本地文件一定要转换成 UTF-8的编码格式

print(df)
# encoding=utf-8
import pandas as pd
import numpy as np
from pandas import read_excel
df = pd.read_excel("C://Users//baihua//Desktop//Untitled.xlsx",sheetname='2') #可以导入指定sheet表
print(df)
from pandas import DataFrame
df = DataFrame({
'age': [21, 22, 23],
'name': ['KEN', 'John', 'JIMI']
})

df.to_csv("C://Users//baihua//Desktop//df.csv",sep=',',header=True,index=False)#index默认True,导出行序号;header默认为true,导出列名

1完整性&空行

删除:观看数据分布,如果缺失数据不多,就删除数据缺失的记录;(数据少,这种方法就不可取;或是缺失数据非随机,删除就可能导致数据从正态变为非正态)

均值:使用当前列的均值;(数据正态分布用均值替换NA较好)

中位数:使用当前列的中位数;(数据分布由于异常值存在而不是正太分布的情况下,使用中位数效果比较好。

高频:使用当前列出现频率最高的数据。(容易改变数据的分布

不常用:0代替缺失值(对极端值,平均值影响较大)

相似:用k近邻的方法,寻找相似值来替换缺失值;(缺失值填补的准确性就要看聚类结果的好坏了,而聚类变数较大)

拟合:如果缺失后数据符合回归趋势,那么就拟合方程测定缺失值;(缺失值连续,才可以使用回归预测,但预测方程出来了,反过去填缺失值,不是显得白痴!

# encoding=utf-8
import pandas as pd
import numpy as np

df = pd.read_csv("C://Users//baihua//Desktop//ceshi.csv",encoding='utf-8') #这里要注意,如果文件中有中文,本地文件一定要转换成 UTF-8的编码格式

print(df)
df.dropna(how='all',inplace=True) #删除空行
print(df)
df['Population'].fillna(df['Population'].mean(), inplace=True)#xx列缺失值用平均数替换
print(df)
df['Population'].fillna(df['Population'].median(), inplace=True)#xx列缺失值用中位数替换
print(df)
age_maxf = df['Population'].value_counts().index[0]
df['Population'].fillna(age_maxf, inplace=True)#xx列缺失值用出现频率最高的的数代替

print(df)我们发现数据中有一个空行,除了 index 之外,全部的值都是 NaN。Pandas 的 read_csv() 并没有可选参数来忽略空行,可以通过dropna来删除空行。python内置函数使用:变量=操作对象.函数

2. 全面性文末有数据集下载

#修改列名
# encoding=utf-8
import pandas as pd
import numpy as np
df = pd.read_excel("C://Users//baihua//Desktop//accountMessage.xlsx",encoding='utf-8') #这里要注意,如果文件中有中文,本地文件一定要转换成 UTF-8的编码格式
print(df)
df.rename(columns={1:'Firstname', 2:'Lastname',3:'Age',4:'Weight'}, inplace =True)#字典的好处就是可以随意修改列命,没修改的默认
print(df)
weight 列的数值,我们能发现 weight 列的单位不统一。有的单位是千克(kgs),有的单位是磅(lbs)。
这里我使用千克作为统一的度量单位,将磅(lbs)转化为千克(kgs):
# encoding=utf-8
import pandas as pd
import numpy as np
df = pd.read_excel("C://Users//baihua//Desktop//accountMessage.xlsx",encoding='utf-8') #这里要注意,如果文件中有中文,本地文件一定要转换成 UTF-8的编码格式
print(df)
df.rename(columns={1:'Firstname', 2:'Lastname',3:'Weight',4:'Age'}, inplace =True)
print(df)
# 获取 weight 数据列中单位为 lbs 的数据
rows_with_lbs = df['Weight'].str.contains('lbs').fillna(False)
print(df[rows_with_lbs])
# 将 lbs 转换为 kgs, 2.2lbs=1kgs
for i,lbs_row in df[rows_with_lbs].iterrows():
Weight=int(float(lbs_row['Weight'][:-3])/2.2)## 截取从头开始到倒数第三个字符之前,即去掉 lbs。
df.at[i,'Weight'] = '{}kgs'.format(Weight)
print(df)


3合法性

在数据中不难发现,姓名列(Name)包含了两个参数 Firtname 和 Lastname,我们使用 Python 的 split 方法,str.split(expand=True),将列表拆成新的列,再将原来的 Name 列删除。

# 切分名字,删除源数据列(切分名字实际生成了新列,新列会添加到最后)
df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
# 删除非 ASCII 字符
df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
print(df)


4唯一性

我们校验一下数据中是否存在重复记录。如果存在重复记录,就使用 Pandas 提供的 drop_duplicates() 来删除重复数据。df.

drop_duplicates(['first_name','last_name'],inplace=True)
print(df)

最后做一个完整的数据处理练习:

# encoding=utf-8
import pandas as pd
import numpy as np
import re
df = pd.read_excel("C://Users//baihua//Desktop//kehou.xlsx",encoding='utf-8') #这里要注意,如果文件中有中文,本地文件一定要转换成 UTF-8的编码格式
df['food']=df['food'].str.lower()
df['ounces'].fillna(df['ounces'].median(),inplace=True)
df['ounces']=df['ounces'].apply(lambda a:abs(a))#将ounces列中的负值取绝对值,lambda是匿名函数

参考文献:

数据来源:

提取码:v18o