SQL必知必会(实战:数据清洗)

数据清洗的准则

数据集或多或少地会存在数据质量问题。这里我们使用泰坦尼克号乘客生存预测数据集,你可以从GitHub上下载这个数据集。

数据集格式为 csv,一共有两种文件:train.csv 是训练数据集,包含特征信息和存活与否的标签;test.csv 是测试数据集,只包含特征信息。

数据集中包括了以下字段,具体的含义如下:

训练集给出了 891 名乘客幸存与否的结果,以及相关的乘客信息。通过训练集,我们可以对数据进行建模形成一个分类器,从而对测试集中的乘客生存情况进行预测。不过今天我们并不讲解数据分析的模型,而是来看下在数据分析之前,如何对数据进行清洗。

首先,我们可以通过 Navicat 将 CSV 文件导入到 MySQL 数据库中,然后浏览下数据集中的前几行,可以发现数据中存在缺失值的情况还是很明显的。

数据存在数据缺失值是非常常见的情况,此外我们还需要考虑数据集中某个字段是否存在单位标识不统一,数值是否合法,以及数据是否唯一等情况。要考虑的情况非常多,这里我将数据清洗中需要考虑的规则总结为 4 个关键点,统一起来称之为“完全合一”准则。

好的数据分析师必定是一名数据清洗高手,要知道在整个数据分析过程中,不论是在时间还是功夫上,数据清洗大概都占到了 80%。

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

“完全合一”是个通用的准则,针对具体的数据集存在的问题,我们还需要对症下药,采取适合的解决办法,甚至为了后续分析方便,有时我们还需要将字符类型的字段替换成数值类型,比如我们想做一个 Steam 游戏用户的数据分析,统计数据存储在两张表上,一个是 user_game 数据表,记录了用户购买的各种 Steam 游戏,其中数据表中的 game_title 字段表示玩家购买的游戏名称,它们都采用英文字符的方式。另一个是 game 数据表,记录了游戏的 id、游戏名称等。因为这两张表存在关联关系,实际上在 user_game 数据表中的 game_title 对应了 game 数据表中的 name,这里我们就可以用 game 数据表中的 id 替换掉原有的 game_title。替换之后,我们在进行数据清洗和质量评估的时候也会更清晰,比如如果还存在某个 game_title 没有被替换的情况,就证明这款游戏在 game 数据表中缺少记录。

使用 SQL 对预测数据集进行清洗

了解了数据清洗的原则之后,下面我们就用 SQL 对泰坦尼克号数据集中的训练集进行数据清洗,也就是 train.csv 文件。我们先将这个文件导入到 titanic_train 数据表中:

检查完整性

在完整性这里,我们需要重点检查字段数值是否存在空值,在此之前,我们需要先统计每个字段空值的个数。在 SQL 中,我们可以分别统计每个字段的空值个数,比如针对 Age 字段进行空值个数的统计,使用下面的命令即可:

SELECT COUNT(*) as num FROM titanic_train WHERE Age IS NULL;

当然我们也可以同时对多个字段的非空值进行统计:

SELECT SUM((CASE WHEN Age IS NULL THEN 1 ELSE 0 END)) AS age_null_num, 
SUM((CASE WHEN Cabin IS NULL THEN 1 ELSE 0 END)) AS cabin_null_num 
FROM titanic_train;

每列空值情况

Age_null_num:177
Cabin_null_num:687
Embarked_null_num:2
Fare_null_num:0
Name_null_num:0
Parch_null_num:0
PassengerId_null_num:0
Pclass_null_num:0
Sex_null_num:0
SibSp_null_num:0
Survived_null_num:0
Ticket_null_num:0

在 titanic_train 数据表中,有 3 个字段是存在空值的,其中 Cabin 空值数最多为 687 个,Age 字段空值个数 177 个,Embarked 空值个数 2 个。

既然存在空值的情况,我们就需要对它进行处理。针对缺失值,我们有 3 种处理方式

    1. 删除:删除数据缺失的记录;
    1. 均值:使用当前列的均值;
    1. 高频:使用当前列出现频率最高的数据。

对于 Age 字段,这里我们采用均值的方式进行填充,但如果直接使用 SQL 语句可能会存在问题,比如下面这样。

UPDATE titanic_train SET age = (SELECT AVG(age) FROM titanic_train) WHERE age IS NULL;

这时会报错:

1093 - You can't specify target table 'titanic_train' for update in FROM clause

也就是说同一条 SQL 语句不能先查询出来部分内容,再同时对当前表做修改。

这种情况下,最简单的方式就是复制一个临时表 titanic_train2,数据和 titanic_train 完全一样,然后再执行下面这条语句:

UPDATE titanic_train SET age = (SELECT ROUND(AVG(age),1) FROM titanic_train2) WHERE age IS NULL;

这里使用了 ROUND 函数,对 age 平均值 AVG(age) 进行四舍五入,只保留小数点后一位。

针对 Cabin 这个字段,我们了解到这个字段代表用户的船舱位置,我们先来看下 Cabin 字段的数值分布情况:

SELECT COUNT(cabin), COUNT(DISTINCT(cabin)) FROM titanic_train;

从结果中能看出 Cabin 字段的数值分布很广,而且根据常识,我们也可以知道船舱位置每个人的差异会很大,这里既不能删除掉记录航,又不能采用均值或者高频的方式填充空值,实际上这些空值即无法填充,也无法对后续分析结果产生影响,因此我们可以不处理这些空值,保留即可。

然后我们来看下 Embarked 字段,这里有 2 个空值,我们可以采用该字段中高频值作为填充,首先我们先了解字段的分布情况使用:

SELECT COUNT(*), embarked FROM titanic_train GROUP BY embarked;

我们可以直接用 S 来对缺失值进行填充:

UPDATE titanic_train SET embarked = 'S' WHERE embarked IS NULL;

至此,对于 titanic_train 这张数据表中的缺失值我们就处理完了。

检查全面性

在这个过程中,我们需要观察每一列的数值情况,同时查看每个字段的类型。

因为数据是直接从 CSV 文件中导进来的,所以每个字段默认都是 VARCHAR(255) 类型,但很明显 PassengerID、Survived、Pclass 和 Sibsp 应该设置为 INT 类型,Age 和 Fare 应该设置为 DECIMAL 类型,这样更方便后续的操作。使用下面的 SQL 命令即可:

ALTER TABLE titanic_train CHANGE PassengerId PassengerId INT(11) NOT NULL PRIMARY KEY;
ALTER TABLE titanic_train CHANGE Survived Survived INT(11) NOT NULL;
ALTER TABLE titanic_train CHANGE Pclass Pclass INT(11) NOT NULL;
ALTER TABLE titanic_train CHANGE Sibsp Sibsp INT(11) NOT NULL;
ALTER TABLE titanic_train CHANGE Age Age DECIMAL(5,2) NOT NULL;
ALTER TABLE titanic_train CHANGE Fare Fare DECIMAL(7,4) NOT NULL;

然后我们将其余的字段(除了 Cabin)都进行 NOT NULL,这样在后续进行数据插入或其他操作的时候,即使发现数据异常,也可以对字段进行约束规范。

在全面性这个检查阶段里,除了字段类型定义需要修改以外,我们没有发现其他问题。

然后我们来检查下合法性及唯一性。合法性就是要检查数据内容、大小等是否合法,这里不存在数据合法性问题。

针对数据是否存在重复的情况,我们刚才对 PassengerId 字段类型进行更新的时候设置为了主键,并没有发现异常,证明数据是没有重复的。

对清洗之后的数据进行可视化

我们之前讲到过如何通过 Excel 来导入 MySQL 中的数据,以及如何使用 Excel 来进行数据透视表和数据透视图的呈现。

这里我们使用 MySQL For Excel 插件来进行操作,在操作之前有两个工具需要安装。

首先是 mysql-for-excel,点击这里进行下载;然后是 mysql-connector-odbc,点击这里进行下载。

安装好之后,我们新建一个空的 excel 文件,打开这个文件,在数据选项中可以找到“MySQL for Excel”按钮,点击进入,然后输入密码连接 MySQL 数据库。

然后选择我们的数据库以及数据表名称,在下面可以找到 Import MySQL Data 按钮,选中后将数据表导入到 Excel 文件中。

在“插入”选项中找到“数据透视图”,这里我们选中 Survived、Sex 和 Embarked 字段,然后将 Survive 字段放到图例(系列)栏中,将 Sex 字段放到求和值栏中,可以看到呈现出如下的数据透视表:

从这个透视表中你可以清晰地了解到用户生存情况(Survived)与 Embarked 字段的关系,当然你也可以通过数据透视图进行其他字段之间关系的探索。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • SELECT 查询的基础语法 创建了一个王者荣耀英雄数据表,这张表里一共有 69 个英雄,23 个属性值(不包括英...
    羋学僧阅读 702评论 0 2
  • 一、DDL 的基础语法及设计工具 DDL 的英文全称是 Data Definition Language,中文是数...
    羋学僧阅读 1,167评论 0 0
  • 创建索引有哪些规律? 创建索引有一定的规律。当这些规律出现的时候,我们就可以通过创建索引提升查询效率,下面我们来看...
    羋学僧阅读 3,931评论 0 0
  • SQL99 标准中的连接查询 一、交叉连接 交叉连接实际上就是 SQL92 中的笛卡尔乘积,只是这里我们采用的是 ...
    羋学僧阅读 1,324评论 0 2
  • 数据库中的存储结构是怎样的 记录是按照行来存储的,但是数据库的读取并不以行为单位,否则一次读取(也就是一次 I/O...
    羋学僧阅读 1,383评论 0 0