欢迎光临散文网 会员登陆 & 注册

9 数据清理第一级--清理表格

2022-11-03 16:56 作者:情报工作站  | 我要投稿

9 数据清理第一级--清理表格

我们终于到了! 在确保我们拥有必要的技术技能(本书第一部分)和分析技能(本书第二部分)之后,我们可以开始讨论有效的数据预处理。我们将通过研究数据清洗开始这一旅程。本章将数据清洗分为三个层次:第一、第二和第三层次。随着你在这些层次上的提升,对数据清洗概念的学习将变得更深入、更复杂。我们将谈论它们是什么,它们有什么不同,以及什么类型的情况需要我们执行每个级别的数据清理。此外,对于每个级别的数据清洗,我们将看到需要不同级别数据清洗的数据源的例子。

在本章中,我们将重点讨论数据清理的第一级--清理表格。接下来的两章也是专门讨论数据清理的,但是是第二和第三层次的。

1 数据清理的层次、工具和目的--第九章、第十章和第十一章的路线图

在任何数据分析项目中,最激动人心的时刻之一是当你有一个数据集,你相信它包含了你需要的所有数据,以有效地满足项目的目标。这个时刻通常是在以下情况之一出现的。

- 你已经完成了为你所想的分析收集数据的工作。

- 你已经从不同的数据源进行了广泛的数据整合。数据整合是一个非常重要的技能,我们将在第12章《数据融合和数据整合》中介绍。

- 数据集刚刚与你分享,它包含了你需要的一切。

不管你是如何得到数据集的,这都是一个令人兴奋的时刻。但要注意的是,更多的时候,在你分析数据之前,你还有很多步骤要做。首先,你需要清理数据集。

为了学习和执行数据清洗,我们需要充分了解以下三个方面。

1. 数据分析的目的。

我们为什么要清洗数据集?换句话说,一旦数据集被清理,我们将如何使用它?

2.数据分析的工具。

将使用什么来进行数据分析?Python(Matplotlib/sklearn)?Excel?MATLAB?Tableau?

3.数据清理的程度。

数据集的哪些方面需要清理?我们的清理是在表面层面,即我们只是在清理列的名称,还是我们的清理更深入,即我们要确保记录的数值是正确的?

1.1 数据分析的目的

虽然听起来数据清洗可以单独进行,而不需要我们过多关注分析的目的,但在本章中,我们将看到,更多时候,情况并非如此。换句话说,在清洗数据时,你需要知道你将对数据集进行哪些分析。不仅如此,你还需要确切地知道你心目中的分析方法和可能的算法将如何使用和操作数据。

到目前为止,在本书中,我们已经了解了四个不同的数据分析目标:数据可视化、预测、分类和聚类。我们了解了这些分析目标以及如何操作数据来满足这些目标。我们需要对这些目标有更深刻的理解和体会,以便它们能够支持我们的数据清理。

通过了解数据在我们清理后将如何被使用,我们就能对数据的清理方式做出更好的决定。在本章中,我们将看到,我们对分析目标的深入理解将指导我们进行更有效的数据清洗。

1.2 数据分析的工具

你打算使用的软件工具对你如何进行数据清理也有重要作用。例如,如果您打算使用MATLAB来进行聚类分析,并且您已经在Python中完成了数据清理,并且拥有Pandas DataFrame格式的完整数据,您将需要把数据转化为MATLAB可以读取的结构。也许你可以使用.to_csv()将DataFrame保存为.csv文件,并在MATLAB中打开该文件,因为.csv文件几乎与任何软件兼容。

1.3 数据清理的层次

数据清理过程既有高层次的目标,也有许多琐碎的细节。不仅如此,从一个项目到另一个项目,需要做的数据清理工作可能完全不同。因此,我们不可能就如何进行数据清理给出明确的、循序渐进的指示。然而,我们可以粗略地将数据清理程序分为三个层次,具体如下。

1. 第一层次:清理表格。

2. 第二级。解除包装,重组,并重新制定表格。

3. 第三级:评估和纠正数值。

在本章和接下来的两章中,我们将了解属于前述层次之一的各种数据清理情况。虽然这些层次在本书中都有专门的章节,但我们将在这里简单介绍一下它们是什么,以及它们之间有什么不同。

第一级--清理表格

这一级的清理都是关于表格的外观。一级清理的数据集有三个特点:它是标准的数据结构,它有可编码的、直观的列标题,并且每一行都有一个唯一的标识符

第二级--重组和重新制定表格

这个级别的清理与你需要你的数据集的数据结构和格式类型有关,这样你心中的分析才能完成。大多数时候,你用于分析的工具决定了数据的结构和格式。例如,如果你需要使用plt.boxplot()创建多个箱形图,你需要为每个箱形图分开数据。例如,请参阅第5章 "数据可视化 "中的 "使用箱形图比较人群 "的例子,在使用函数绘制多个箱形图之前,我们对数据进行了重组。

第三层次--评估和纠正数值

这个层次的清理是关于数据集中记录的数值的正确性和存在性。在这个层次的清理中,你要确定记录的数值是正确的,并以最能支持分析目标的方式呈现。这一层次的数据清理是数据清理过程中技术性和理论性最强的部分。我们不仅需要知道我们将要使用的工具需要数据是怎样的,而且我们还需要了解数据应该如何被修正、组合或删除,这是由分析过程的目标所决定的。处理缺失值和处理异常值(outliers)也是这个层次的数据清理的主要部分。

到目前为止,我们已经看了数据清理的三个最重要的维度:数据分析的目的,数据分析的工具,以及三个数据清理级别。

接下来,我们将了解这三个维度--分析目的、分析工具和数据清理级别--在有效的数据清理方面所发挥的作用。

1.4 将分析的目的和工具映射到数据清理的层面上

下图显示了这三个层面的地图。拥有一个经过一级清理的数据集是最重要的第一步,花时间确保这个级别的数据清理已经完成,将使接下来的数据清理级别和数据分析过程更加容易。虽然我们可以在不知道我们对数据集的分析方法的情况下进行I级数据清理,但在不知道软件工具或你打算采用的分析方法的情况下进行任何II级或III级数据清理是不明智的。

下图显示,二级数据清理需要在你了解工具和分析目标的情况下进行,而三级数据清理需要在你了解数据分析目标后执行

在本章的其余部分,我们将通过提供往往经常出现的数据清洗实例,更详细地介绍数据清洗级别I。在接下来的几章中,我们将对数据清洗级别II和III做同样的事情。

2 数据清理第一级--清理表格

数据清理第一级的数据预处理步骤最不深入。大多数时候,你可以不在第一级进行数据清洗。然而,如果有一个经过第一级清洗的数据集,将是非常有意义的,因为这将使其余的数据清洗过程和数据分析变得更加容易。

当数据集具有以下特征时,我们将考虑I级数据集的清洁。

- 它的数据结构是标准的和首选的。

- 它有可编码的、直观的列标题

- 每一行都有一个唯一的标识符

下面的三个例子至少有一个特征,或者是前面的特征的组合,以方便学习。

2.1 例子1--不理智的数据收集

时不时地,你可能会遇到没有以最佳方式收集和记录的数据来源。这些情况发生在数据收集过程是由不具备适当的数据库管理技能的人或团体完成的。不管为什么会出现这种情况,你获得的数据源需要进行大量的预处理,才能放到一个标准的数据结构中。

例如,想象一下,你受雇于一个选举活动,利用数据的力量来帮助推动选举。奥米德在你之前刚被雇用,他对选举的政治方面了解很多,但对数据和数据分析了解不多。你被指派加入奥米德,帮助处理他所负责的工作。在你们的第一次会议上,你意识到任务是分析美国第45任总统唐纳德-特朗普的演说。为了让你了解情况,他微笑着告诉你,他已经完成了数据收集过程,现在需要做的就是分析;他向你展示了他电脑上的一个文件夹,其中包含唐纳德-特朗普在2019年和2020年的每一次演讲的文本文件(.txt)。下面的截图显示了奥米德电脑上的这个文件夹。

在查看了这个文件夹后,你立刻意识到在考虑任何分析之前,必须进行数据预处理。为了与Omid建立良好的工作关系,你没有直接告诉他需要做一个巨大的数据预处理任务;相反,你评论了他的数据收集中很好的方面,可以作为数据预处理的基石。你提到,这些文件的命名遵循一个可预测的顺序,这很好。这个顺序是:城市名称在前,接着是作为三个字母的月份名称,然后是作为一个或两个数字的日子,最后是作为四个数字的年份。

由于你精通Pandas DataFrame,你建议将数据处理成DataFrame,Omid急于学习,接受了建议。

你可以执行以下步骤将数据处理成一个DataFrame。

1. 首先,我们需要访问文件名,这样我们就可以用它们来打开和读取每个文件。注意:我们可以自己输入文件名,因为只有35个文件。然而,我们必须使用编程来做这件事,因为我们正在努力学习可扩展的技能;想象一下,我们有一百万个文件,而不是35个。下面的代码显示了如何使用os模块中的listdir()函数可以非常容易地为我们做到这一点。

from os import listdir
FileNames = listdir('/Users/peanut123/Desktop/Hands-On-Data-Preprocessing-in-Python-main/Chapter09/Speeches')
FileNames

2. 接下来,我们需要为我们的数据创建一个占位符。在这一步,我们需要想象一下在这个数据清理过程完成后,我们的数据集会是什么样子。我们希望有一个DataFrame,包含每个文件的名称和内容。下面的代码使用pandas模块来创建这个占位符。

import pandas as pd
speech_df = pd.DataFrame(index=range(len(FileNames)),columns=['File Name','The Content'])
speech_df.head()

3. 最后,我们需要打开每个文件,将其内容插入我们在上一步创建的speech_df中。下面的代码循环浏览FineNames的元素。由于每个元素都是其中一个文件的名称,可以用来打开和读取文件,我们可以在这里使用open()和.readlines()函数。

dir_url = '/Users/peanut123/Desktop/Hands-On-Data-Preprocessing-in-Python-main/Chapter09/Speeches/'
for _,f_name in enumerate(FileNames):
    f = open(dir_url+f_name,'r',encoding='utf-8')
    f_content = f.readlines()
    f.close()
    speech_df.at[_,'File Name'] = f_name
    speech_df.at[_,'The Content'] = f_content
    break
speech_df.head()

完成这三个步骤后,运行Print(speech_df),并在继续前进前研究它。在这里,你可以看到speech_df具有第一级清理过的数据的三个特征中的两个。该数据集具有第一个特征,因为它现在是一个标准的数据结构,这也是你的首选。

数据集在被处理成speech_df后,也有第三个特征,因为每一行都有一个唯一的索引。你可以运行 speech_df.index 来调查这一点。

你可能会惊喜地发现,我们并没有做任何事情来获得这个清洗特征。这是由Pandas自动为我们完成的。

然而,关于第二个特征,我们本可以做得更好。文件名和内容列的名称足够直观,但它们并不像它们可以被编码的那样。我们可以使用df['ColumnName']方法访问它们,但不能使用df.ColumnName,如图所示。

1. 首先,运行 speech_df['File Name']和 speech_df['The Content'];你会看到,用这种方法可以很容易地访问每一列。

2. 第二,运行 speech_df.File Name 和 speech_df.The Content;你会得到错误。为什么?为了唤起你的记忆,请回到第一章,回顾NumPy和Pandas的核心模块,找到DataFrame访问列的部分,并研究图1.16所示的错误。这里的错误原因非常相似。

所以,在使用Pandas DataFrame时,为了使列的标题可以编排,我们只需要遵循一些准则,如下所示。

- 尽量缩短列的标题,不要让它们变得不直观。例如,"The Content "可以简单地称为 "Content"。

- 避免在列的名称中使用空格和可能的编程运算符,如-、+、=、%和&。如果你必须有一个以上的词作为列的名称,要么使用驼峰命名(FileName),要么使用下划线(File_Name)。

你可能已经注意到,在倒数第二段代码中,我可以使用更多可编码的列标题;我可以使用 columns=['FileName', 'Content'] 而不是 columns=['File Name', 'The Content'] 。你是对的。我应该在那里这样做的;我这样做只是为了事后能够提出这个观点。所以,在继续前行之前,先去改进代码。另外,你也可以用下面的代码将列名改为可编码的版本。

speech_df.columns = ['FileName','Content']
speech_df.head()

现在我们已经完成了这个例子,让我们回顾一下这个例子中的数据源需要的一级数据清洗的特征。这个数据源需要I级数据清洗的所有三个特征来进行改进。我们必须明确地采取行动,确保数据是标准的数据结构,同时具有直观的、可编码的列名。另外,我们使用的工具,Pandas,自动给每一行一个唯一的标识符

2.2 实例2--重新索引(多级索引)

在这个例子中,我们想对TempData.csv进行一级数据清理。下面的截图显示了如何使用Pandas将数据读入一个DataFrame。

air_df = pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Hands-On-Data-Preprocessing-in-Python/main/Chapter09/TempData.csv')
air_df.head()

我们对数据集的第一次评估显示,数据是在一个标准的数据结构中,列的标题是直观的和可编码的,而且每一行都有一个唯一的标识符。然而,仔细观察后,Pandas分配的默认索引是唯一的,但对识别行没有帮助年、月、日和时间列作为行的索引会更好。所以,在这个例子中,我们想用不止一列来重新索引DataFrame。我们将使用Pandas的特殊能力,即多级索引。我们在Pandas的多级索引部分第一章 "回顾NumPy和Pandas的核心模块 "中介绍了这一点。

这可以通过使用Pandas DataFrame的.set_index()函数来轻松实现。

然而,在这之前,我们先把年份这一栏删除,因为它的值只有2016。为了检查这一点,运行air_df.Year.unique()。在下面一行代码中,为了不丢失说明这个数据集是2016年的信息,我们将把DataFrame的名称改为air2016_df

air2016_df = air_df.drop(columns=['Year'])
air2016_df.head()

现在,不必要的列已经被删除,我们可以使用.set_index()函数来重新索引DataFrame。

air2016_df.set_index(['Month','Day','Time'],inplace=True)
air2016_df.head()

如果你在运行前面的代码后打印air2016_df,你会得到具有多级索引的DataFrame,如下面的截图所示。

我们在这里的成就是,不仅每一行都有一个唯一的索引,而且索引可以用来有意义地识别每一行。例如,你可以运行air2016_df.loc[2,24,'00:30:00']来获得2月24日午夜后30分钟的温度值。

在这个例子中,我们专注于第一级数据清理的第三个特征:每一行都有一个唯一的标识符。在下面的例子中,我们将重点关注第二个特征:有一个可编码的、直观的列名。

2.3 例3--直观但长的列标题

在这个例子中,我们将使用OSMI 2019年技术中的心理健康调查。

csv从https://osmihelp.org/research。下面的截图显示了将数据集读入 response_df 的代码,然后使用 .head() 函数显示数据的第一行。

response_df = pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Hands-On-Data-Preprocessing-in-Python/main/Chapter09/OSMI%20Mental%20Health%20in%20Tech%20Survey%202019.csv')
response_df.head()

从编程和可视化的角度来看,处理一个列标题很长的数据集会很困难。例如,如果你想访问数据集的第六列,你将不得不输入以下一行代码。

response_df['Do you know the options for mental health care available under your employer-provided health coverage?']

对于我们不能为列设置简短而直观的标题的情况,我们需要使用一个列字典。我们的想法是用一个键来代替每一个列的完整标题,这在一定程度上是直观的,但明显更短。如果需要的话,这个字典也会通过相关的键提供对全标题的访问。

下面的代码使用Pandas系列创建了一个列字典。

keys = ['Q{}'.format(i) for i in range(1,83)]
columns_dic = pd.Series(response_df.columns,index=keys)
columns_dic.head()

前面的代码将创建字典栏的过程分成两步。

1. 首先,代码创建了keys变量,它是列标题的简短替代物的列表。这是用一个列表理解技术完成的。

2. 其次,代码创建了一个名为columns_dic的Pandas系列,其索引是key,其值是response_df.columns。

一旦前面的代码运行成功,columns_dic熊猫系列就可以作为一个字典来使用。例如,如果你运行columns_dic['Q4'],它将给你第四列(第四个问题)的完整标题。

接下来,我们需要更新response_df的列,这可以用一行简单的代码完成:response_df.columns = keys。一旦你完成了这项工作,response_df就会有简短而有点直观的列标题,其完整的描述可以很容易地访问。下面的截图显示了在执行了前面的步骤后,response_df的转换版本。

response_df.columns = keys
response_df.head()

在这个例子中,由于数据集在第一和第三特征方面处于良好状态,所以我们采取了措施来确保第一级数据清理的第二个特征已经得到满足。

到目前为止,你已经通过实例学习并实践了一些数据清洗的例子。在下一章,我们将学习并看到二级数据清洗的例子。


9 数据清理第一级--清理表格的评论 (共 条)

分享到微博请遵守国家法律