数据清洗

数据清洗在整个数据分析过程中占比最大,通常要80%左右

就拿做饭打个比方,对于很多人来说,热油下锅、掌勺翻炒一定是做饭中最过瘾的环节

但实际上炒菜这个过程只占做饭时间的20%,剩下80%的时间都是在做准备,比如买菜、择菜、洗菜等等

数据质量的准则

数据清洗规则可以总结为以下4个关键点,统一起来叫“完全合一”

  • 完整性:单条数据是否存在空值,统计的字段是否完善
  • 全面性:观察某一列的全部数值,比如在Excel中,我们选中一列,可以看到该列的平均值、最大值、最小值
    • 我们可以通过常识来判断该列是否有问题,比如:数据定义、单位标识、数值本身
  • 合法性:数据的类型、内容、大小的合法性。比如数据中存在非ASCII字符,性别存在了未知,年龄超过了150岁等
  • 唯一性:数据是否存在重复记录,因为数据通常来自不同渠道的汇总,重复的情况是常见的
    • 行数据、列数据都需要是唯一的,比如一个人不能重复记录多次,且一个人的体重也不能在列指标中重复记录多次

根据清洗规则,能够保证数据标准、干净、连续,为后续数据统计、数据挖掘做好准备

如果想要进一步优化数据质量,还需要在实际案例中灵活使用

清洗数据,一一击破

  0 1 2 3 4 5 6 7 8 9
0 1.0 Mickey Mousè 56.0 70kgs 72.0 69 71.0 - - -
1 2.0 Donald Dunck 34.0 154.89lbs - - - 85 84 76
2 3.0 Mini Mòuse 16.0 NaN - - - 65 69 72
3 4.0 Scrooge McDuck 78kgs 78 79 72 - - -
4 5.0 Pink Panther 54.0 198.658lbs - - - 69 75
5 6.0 Huey McDuck 52.0 189lbs - - - 68 75 72
6 7.0 Dewey McDuck 19.0 56kgs - - - 71 78 75
7 8.0 Scoopy Doo 32.0 78kgs 78.0 76 75.0 - - -
8 NaN NaN NaN NaN
9 9.0 Huey McDuck 52.0 189lbs - - - 68 75 72
10 10.0 Louie McDuck 12.0 45kgs - - - 92 95 87

这是一家服装店统计的会员数据。最上面的一行是列坐标,最左侧一列是行坐标

列坐标中,第 0 列代表的是序号,第 1 列代表的会员的姓名,第 2 列代表年龄,第 3 列代表体重

第 4~6 列代表男性会员的三围尺寸,第 7~9 列代表女性会员的三围尺寸

刚看到这个表格的时候,是不是有一种一脸懵逼的感觉

下面,我们就依照“完全合一”的准则,使用Pandas来进行清洗

  1. 完整性
    • 缺失值,体重、年龄、三围等都有缺失值,一般使用以下方法处理
      • 删除:删除数据缺失的记录
      • 均值:使用当前列的均值
      • 高频:使用当前列出现频率最高的数据
    • 空行,数据中有一个空行,除了index外,全是空值
      • 删除:删除数据缺失的记录
  2. 全面性
    • 列数据的单位不统一,体重列的数值单位不统一,有的是千克,有的是磅
      • 使用千克作为统一度量单位,将磅转换为千克
  3. 合理性
    • 非ASCII字符,姓名列出现了一些特殊字符
      • 删除或替换非ASCII字符
  4. 唯一性
    • 一列有多个参数,Name可以拆分为Firstname和Lastname
    • 重复数据,Huey McDuck的数据重复了
      • 去重处理
      • 如果名称相同,其他数据不同,可以根据实际场景合并去重
import pandas as pd

# 优化打印样式
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

df = pd.read_excel("data.xlsx")

# 设置表头名称
df.rename(
    columns={"\t": "", 0: "number", 1: "name", 2: "age", 3: "weight", 4: "bust_man", 5: "waistline_man", 6: "hips_man",
             7: "bust_women", 8: "waistline_women", 9: "hips_women"}, inplace=True)

# 完整性
# 1.使用平均值填充
df['age'].fillna(df['age'].mean(), inplace=True)
# 2.使用高频值填充
df['age'].fillna(df['age'].value_counts().index[0], inplace=True)
df['bust_man'].replace("-", None, inplace=True)
df['bust_man'].fillna(df['bust_man'].mean(), inplace=True)
# 3.删除名字为空的行
df.dropna(subset=["name"], inplace=True)

# 全面性
# 找出体重单位为磅的行,不包括NaN的行
rows_with_lbs = df['weight'].str.contains('lbs').fillna(False)
# 遍历行,将磅转换为千克,1kgs=2.2lbs
for i, lbs_row in df[rows_with_lbs].iterrows():
    weight = int(float(lbs_row['weight'][:-3]) / 2.2)
    df.at[i, 'weight'] = '{}kgs'.format(weight)

# 合理性
# 使用正则把è等非ASCII字符替换成空
df['name'].replace(r'[^\x00-\x7F]+', '', inplace=True, regex=True)

# 唯一性
# 1.将name拆分成first_name和last_name
df[['first_name', 'last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
# 2.将name重复的数据删除掉
df.drop_duplicates(['first_name', 'last_name'], inplace=True)

print(df)

养成数据审核的习惯

当你从事数据分析相关工作的时候,你会发现养成数据审核的习惯非常重要

第三方的数据要清洗,自有产品的数据,也是需要数据清洗

比如:自由产品是一个投票系统,那你就去清洗掉爬虫数据、作弊数据等

可以说没有高质量的数据,就没有高质量的数据挖掘,而数据清洗是高质量数据的一道保障

results matching ""

    No results matching ""