2.1 Pandas科学计算库
在数据分析工作中,Pandas的使用频率是很高的。一方面是因为Pandas提供的基础数据结构DataFrame与JSON的契合度很高,转换起来很方便。另一方面,如果我们日常的数据清理工作不是很复杂的话,则使用Pandas代码就可以很方便地对数据进行规整。
2.1.1 初识Pandas
Pandas由AQR Capital Management于2008年开发,并于2009年年底开源发布,目前由专注于Python数据包开发的PyData开发团队继续开发和维护。
Pandas是基于NumPy构建的含有更高级数据结构和分析能力的工具包。Pandas的核心数据结构是Series和DataFrame,它们分别代表着一维的序列和二维的表结构。基于这两种数据结构,Pandas可以对数据进行导入、清洗、处理、统计和输出。它是支撑Python成为强大而高效的科学计算语言的重要因素之一。
由于Pandas是Python的第三方库,需要另外安装:
安装完成后,我们来查看Pandas版本,代码如下:
下面我们通过一个例子来体验Pandas的操作,感受它的科学计算能力。
【例2-1】 Pandas基本操作。
运行程序,输出如下:
在例2-1中,利用NumPy构建了一个Pandas库下的DataFrame对象,并对其进行了一些基本操作,以方便读者对Pandas进行理解。由结果可看出,Pandas在数据预处理与数据挖掘过程中起着非常重要的作用。
2.1.2 Pandas的相关操作
1. 数据结构
目前,Pandas中的数据结构有3种,分别为Series、DataFrame和Panel,如表2-1所示。
表2-1 Pandas中的3种数据结构
2. Series结构
Series是Pandas中最基本的对象,它定义了NumPy的ndarry对象的接口array(),因此可以利用NumPy的数组处理函数直接处理Series对象。一个Series是一个一维的数据对象,其中每一个元素都有一个标签,标签可以是数字或字符串。Series对象具有列表和字典的属性(字典的属性由索引赋予)。
Series的基本创建方式为:
其中:
• data:传入数据,可以传入多种类型。
• index:索引,在不指定index的情况下,默认数值索引range(0,len(data))。
【例2-2】 创建Series。
运行程序,输出如下:
3. DataFrame结构
DataFrame(数据框)是表格型的二维数据结构,特点如下。
• 列内的元素同类型,不同的列之间可以不相同。
• 索引有两个轴向:axis=0或'index'行,axis=1或'columns'列。分别用df.index(行名)与df.columns(列名)调用。
在数据处理中,使用数据框是非常便捷的;而系列(Series)我们却很少使用。DataFrame的基本创建方式为:
• data:传入数据,可以传入多种类型数据。
• index:列索引,不指定自动数值索引填充。
• columns:行索引,不指定自动数值索引填充。
【例2-3】 创建DataFrame。
运行程序,输出如下:
还可以使用字典创建DataFrame。例如:
运行程序,输出如下:
4. Panel结构
Panel创建的是三维的表,其创建方式为:
其中:
• items:坐标轴0,索引对应的元素是一个DataFrame。
• major_axis:坐标轴1,DataFrame里的行标签。
• minor_axis:坐标轴2,DataFrame里的列标签。
【例2-4】 创建三维数组,分别对应相应的item、major_axis和minor_axis。
运行程序,输出如下:
通过前面的介绍,可以初步了解Pandas在内存中的基本操作。需要注意,数据的行列信息(index、columns)。同时Pandas也支持本地读取文件,如pd.to_csv读取csv文件等,具体如表2-2所示。
表2-2 Pandas读取文件
5. 数据的选取与清洗
对DataFrame进行选择,要从3个层次考虑:行列、区域和单元格。
(1)使用方括号[]选取行列。
使用方括号[]选取,返回的是一维数组——行维度。输入要求是整数切片、标签切片、布尔数组,具体规则如表2-3所示。
表2-3 使用方括号[]选取行列规则
(2)df.loc[]用于标签定位,[]内为行和列的名称,下面直接通过一个例子来演示其用法。
【例2-5】 df.loc[]的用法。
运行程序,输出如下:
当然,获取某列数据最直接的方式是df.[列标签],但是当列标签未知时可以通过这种方式获取列数据。
需要注意的是,dataframe的索引[1:3]是包含1、2、3的,与平时的不同。
(3)df.iloc[]可通过行号获取行数据。下面通过一个例子来演示其用法。
【例2-6】 df.iloc[]的用法。
运行程序,输出如下:
(4)df.ix[]是iloc和loc的合体。下面通过一个例子来演示其用法。
【例2-7】 df.ix[]的用法。
运行程序,输出如下:
6. 数据清洗
无论是数据挖掘工程师、机器学习工程师,还是深度学习工程师,都非常了解数据真实性的重要性,数据真实性决定特征维度的选择规则。数据准备阶段(包含数据的抽取、清洗、转换和集成)的工作量常常占据全部工作的50%左右。而在数据准备的过程中,数据质量差又是最常见而且最令人头痛的问题之一。本节针对缺失值和特殊值这种数据质量问题提出了推荐的处理方法。
【例2-8】 构建DataFrame。
运行程序,输出如下:
利用dropna()可以实现对缺失值的处理,下面的代码实现了对df2缺失值的处理:
可用的填充方法如表2-4所示。
表2-4 可用的填充方法
注意:处理时间序列数据,使用pad/ffill十分常见,因此“最后已知值”在每个时间点都可用。ffill()等效于fillna(method= 'ffill'),bfill()等效于fillna(method= 'bfill')。
通常我们想用其他值替换任意值。在Series/DataFrame中可以使用replace(),它提供了一种高效而灵活的方法来执行此类替换。
【例2-9】 利用replace()对例2-8中的数据进行替换。
通常,在数据预处理时,如果数据特征维度比较大,则我们会丢弃一些弱特征。如果在DataFrame中需要标识和删除重复行,那么有两种有效的方法:duplicated和drop_duplicates。每种方法都将以标识重复行的列作为参数。
• duplicated:返回布尔向量,其长度为行数,并指示行是否重复。
• drop_duplicates:删除重复的行。
在默认情况下,重复集的第一个观察到的行被认为是唯一的,但每个方法都有一个keep参数来指定要保留的目标。
• kepp='first'(默认):除第一次出现外,标记/删除重复项。
• kepp='last':标记/删除除了最后一次出现的副本。
• kepp='False':标记/删除重复项。
【例2-10】 对例2-8中的数据进行标识和删除重复行。