1.1 文件中的数据
文件是计算机科学中的常用术语。文件能用于保存数据,而且是多种多样的,如文本文件、图像文件和办公软件生成的二进制文件等。不同文件中的数据也有差别,有的数据是结构化的,有的数据是非结构化的。本节将向读者介绍数据科学项目中常用到的三种文件,并重点演示如何从文件中读取数据。
结构化数据是指关系型数据库中用二维表格表达和存储的数据,每个数据有严格的数据格式和规范。非结构化数据(如图像、视频等)则不能用二维表格形式表达和存储。
1.1.1 CSV文件
CSV(Comma-Separated Values,逗号分隔值)是以纯文本方式保存数据的常用文件格式,其中的数据属于结构化数据。
基础知识
用电子表格工具软件可以打开CSV文件,如图1-1-1所示。
图1-1-1 用电子表格工具软件打开的CSV文件
处理电子表格文件的常用工具,包括微软的Excel和WPS中的电子表格软件,也可以使用在线电子表格,如腾讯文档。
读者对电子表格软件一定不陌生,本书不再赘述操作方法。在数据科学项目实践中,也会有很多场景应用这类软件,请读者不要排斥。一切工具的目的都是得到符合预期的数据。只不过因为电子表格软件不是本书的重点内容,所以后面不再提及该工具,但不意味着不可以应用它。
下面重点说明使用Python编程语言读取CSV文件的数据。
path是本书开发环境中的数据集目录,读者要根据自己的开发环境进行修改。
In[1]第5行里的“# ①”表示注释,程序执行时忽略此内容。
老齐教室微信扫描二维码,关注我的公众号
为了便于学习,可以按照“前言”中的说明关注与本书相关的微信公众号,从而获得学习用数据集和加入在线实验平台。在代码示例中,用“/jiangsu/cities.csv”方式表示此文件在数据源目录中的地址。
附录A:简要介绍Jupyter。
以上代码在Jupyter notebook中调试。Jupyter是数据科学中常用的工具——详细使用方法请阅读“扩展探究”中推荐的资料。
用Python标准库的csv模块能够读取CSV文件内容,但在In[1]的①中得到的是一个迭代器对象,必须使用循环语句才能将文件中每一行读入内存,这使得后续操作很不方便。开发者不允许存在任何“不方便”,因为会降低工作效率,并且,CSV文件是常见的保存数据的文件。因此,必然有更简单且能够更适用于后续操作的方法——如果没有,则是创新的机会。
Python语言生态中的Pandas提供了实现上述诉求的函数——关于Pandas的使用方法请阅读“扩展探究”中推荐的资料。当然,如果读者对In[2]的②所示的函数不满意,也可以自己创造。
关于“迭代器”对象,请参阅《Python大学实用教程》(电子工业出版社出版)。
附录C:简要介绍Pandas。
比较Out[2]和In[1]的输出,此处的结果在显示方式上友好了很多。不仅如此,这里所得到的对象(变量df引用)是数据科学项目中用途最广泛的DataFrame类型的对象。
In[2]的②使用Pandas的read_csv函数读取了指定的CSV文件,此函数的完整参数列表是:
DataFrame是Pandas中的一种对象类型,类似于二维表格。
不需要对这些参数的含义死记硬背,可以使用帮助文档了解。建议读者浏览一遍pd.read_csv函数的帮助文档,当以后需要处理某个特殊问题的时候,可以再次借助帮助文档,查询相应参数。
在Jupyter中输入In[3]的代码并执行,能够显示函数read_csv的完整文档,其中包含对所有参数的解释。
例如,在Out[2]输出的二维数据表格中,以数字序号表示索引。在读取此CSV文件的时候,也可以通过参数指定文件中的某一列作为索引。
In[4]中函数read_csv增设了参数index_col=0,意思是用CSV文件的第0列作为索引,最终得到了Out[4]输出效果。
在In[2]的②中读取到CSV文件之后,返回的是DataFrame对象(②中用变量df引用此对象),有的资料将DataFrame翻译为“数据框”,本书使用英文名称。
推荐阅读《跟老齐学Python:数据分析》(电子工业出版社出版),系统化了解Pandas的各项知识。
项目案例
1.项目描述
读取“/kaggle/diabetes.csv”数据,并了解此数据集的概况。
2.实现过程
In[5]的③读取指定的CSV文件,得到了变量diabetes引用的DataFrame对象。④通过DataFrame实例的属性shape得到了diabetes的形状,Out[5]的输出结果表示diabetes共有765行、9列。如果直接调用diabetes,就会将所有内容显示出来(读者可以在Jupyter中尝试),在页面上占用较多篇幅,为避免这种情况,可以显示部分样本。
In[6]中出现的head方法是DataFrame对象常用的显示部分样本的方法,默认显示前5个,传入整数类型的参数,就可以根据指定数量显示样本。
与head方法类似的,还有tail和sample方法。
比较In[7]和In[8]的执行结果,了解二者的异同。
In[7]和In[8]的功能类似,能够显示出DataFrame对象中每列的数据类型。
动手练习
1.先在github.com网站完成用户注册和登录操作,然后完成如下操作。
●在本地计算机安装git,熟悉常用的git命令。
●在github.com网站创建个人公开代码仓库。
●应用git的push命令将本地指定目录中的文件上传到个人的代码仓库中。
git是源码管理工具,目前已经被普遍采用。
本题目与《Python大学实用教程》的“练习和编程1”第5题相呼应,建议读者查阅有关资料,完成本题各项操作。
2.参考本书附录或者推荐的书籍,完成如下操作。
(1)在本地计算机安装并运行Jupyter。
(2)在本地计算机安装Pandas、Numpy。
3.用Pandas读取“/bicycle/Bicycle_Counts.csv”文件的数据,并完成如下操作。
(1)以第1列为索引,并显示前10个样本。
(2)返回此数据集的样本总数。
(3)将(1)所显示的数据保存到一个新的CSV文件中。
扩展探究
1.Jupyter是基于浏览器的代码编辑工具,在数据科学中被广泛采用,其官方网站是https://jupyter.org/。建议读者根据网站文档安装此工具,并学会使用。
2.Numpy和Pandas是Python语言在数据科学中的重要工具,使用Python语言的数据科学项目都必须使用它们。本书在后续各种操作中会对涉及的一些函数(方法)给予必要的介绍,但是不能替代读者系统化学习。建议阅读《跟老齐学Python:数据分析》,系统学习Numpy和Pandas的有关知识。
3.在数据科学中,安装第三方模块(包)的方式,依然可以使用Python语言中常用的pip命令(参阅《Python大学实用教程》)。此外,还有另一个专门的数据科学集成开发工具Anaconda(官方网站:https://www.anaconda.com/),安装此工具之后,数据科学中常用的模块(包)就已经集成在其中,未集成进来的其他模块一般也提供了conda命令的安装方法。更详细的内容请查阅官方文档(https://docs.anaconda.com/)。
1.1.2 Excel文件
Excel文件也是常用于保存数据的文件,《Python大学实用教程》的9.2.2节专门介绍了如何使用Python第三方包读/写此类文件,请读者参阅。本节将重点介绍如何用Pandas从Excel文件中读取数据。
基础知识
在Jupyter中输入pd.read_,然后按下Tab键,就可以出现如图1-1-2所示的效果,从这里可以看到多个以“read”开始的函数名称——Python中规范的命名方式遵循着“望文生义”的原则。
图1-1-2 Tab键辅助记忆
利用Tab键可以查找函数,减轻记忆负担。
在学习和工作过程中,都应该充分利用帮助文档。In[3]演示了获得pd.read_csv函数帮助信息的方法,用同样的方法,也可以查看pd.read_excel函数的文档内容。
依然建议读者认真阅读文档内容,了解此函数的基本使用方法。在帮助文档的后面,通常还会有学习示例。
下面就使用这个函数读取Excel文件的数据。
path为In[1]中创建的变量。
除了如In[10]中的代码那样读取Excel文件,还可以利用电子表格软件将Excel文件转化为CSV文件,然后利用Pandas的read_csv函数读取文件。
如果将已有的数据,如DataFrame类的数据,保存为Excel或者CSV文件,应当如何操作?
继续使用如图1-1-2所示的方法,在Jupyter中输入“jiangsu.to_”,然后按Tab键,显示如图1-1-3所示的结果。
图1-1-3 保存为某种文件的函数
从这里可以看到,DataFrame对象实例保存为某种格式文件的方法(用这种方法找到解决1.1.1节“动手练习”中第3题所需要的方法)。读者应该认真观察图1-1-2和图1-1-3显示的函数(方法)名称,从而了解到Pandas可以读、写什么格式的文件。
在Jupyter中执行shell命令查看当前目录内容的方式:
即在命令前面写上“!”符号(英文状态)。
如果没有报错和其他显示,则说明已经保存成功。若不放心,可以到目录中查看是否已有保存的文件。
项目案例
1.项目描述
从“国家数据”网站(http://data.stats.gov.cn/)下载“全国居民消费价格分类指数”,并用柱形图表示指数的变化。
2.实现过程
打开“国家数据”网站,完成注册、登录步骤,然后根据导航信息,进入如图1-1-4所示的界面,下载所显示的数据。
图1-1-4 下载“全国居民消费类价格分类指数”
由于日期不同,读者打开此页面所看到的数据可能与图1-1-4有所差异。
将下载的文件更名为cpi.xls,用电子表格软件打开之后的基本样式如图1-1-5所示。
图1-1-5 Excel文件内容部分截图
可以利用电子表格软件对数据进行整理。因本书为了演示Pandas的应用,故在此无过多的操作。
在Jupyter中,利用pd.read_excel函数读入此文件。
因受篇幅所限,以上只显示部分列,请读者在调试的时候查看全部列的内容。
对照图1-1-5,理解缺失值产生的原因。
从显示内容可知,这个数据集不能直接用于绘图,比如第0行,都是缺失值(用NaN表示);第1行是所统计的年月。因此,对该数据需要整理。
⑥是DataFrame的切片操作。
In[13]中的代码,使用了多种DataFrame对象有关方法和切片操作,最终将Out[12]所显示的数据变换为如Out[13]显示的样子。下面对In[13]中的代码逐行进行简要说明:
⑤替换了数据集中列的名称,变成对应的年月。
⑥截取Out[12]所显示的第2行及其以下的数据。
⑦删除索引号为11和12的两行,并更新原有数据集(inplace=True)。
⑧增加一列,对应于每行的统计指标,即简化原来的“指标”列的表述。
⑨删除“指标”列,并更新数据集。
⑩重新规划索引,删除原来的,实现从0开始重建索引,并更新数据集。
⑪将列索引的名字设置为空,并更新数据集。
注意区分由数字组成的字符串与整数、浮点数的不同。字符串不能参与数学运算。
这个反馈信息表明,每列中的数字,比如102.3,直观地看是浮点数,但Pandas并不认为它是浮点数(显示为object),所以,还要将每列的数据类型转换成浮点数。
In[15]的操作是“特征数值化”(详见3.1节)。
cpi.columns[: -1]得到的是数据集中除最右列名称外的其他列名称,然后用循环语句将每列的数据转换为浮点数(pd.to_numeric(cpi[column])。
下面使用Matplotlib绘制柱形图。为了简化,仅绘制一个指标的各月指数的柱形图。
对于In[16]第1行代码中的“#⑫”,读者在调试程序的时候不要输入。
建议读者参阅“动手练习”中的第1题,继续优化此图不完美(如图底部数字重叠)的显示结果。
用类似方法,可以绘制其他各项指标的柱形图。
但是,请读者特别注意,上述图示并非完美。这里只初步了解实现数据可视化的方法。
⑫的作用是声明将所绘制图像插入当前Jupyter所在浏览器中。注意,这一句必须在且只能在代码块的第1行。
⑬引入绘图模块,通常更名为plt。
⑭绘制柱形图,两个参数分别为x轴和y轴的数据。
⑮为柱形图绘制网格,以便比较观察各个柱的高度。
动手练习
1.在本地计算机上安装Matplotlib,并根据有关资料掌握初步的绘图方法。推荐以下文献资料:
①《跟老齐学Python:数据分析》。
②在线图书《案例上手Python数据可视化》(通过本书作者微信公众号“老齐教室”查阅)。
2.读取数据“/jiangsu/jiangsu.xls”,并绘制各个城市面积(area列)的柱形图。
3.改进“基础知识”中In[10]读取Excel文件的方法,要求将原Excel文件的第1列(“name”列)指定为所得到的DataFrame对象的索引。
4.利用Matplotlib,绘制In[10]所得数据中“population”列的箱线图。
箱线图(Box plot)是一种常见的统计图,能显示数据集中的最大、最小值;上、中、下分位数;平均值;离群值。
扩展探究
1.查阅有关统计学资料,理解常见的柱形图、饼图、折线图、箱线图、散点图等统计图的含义。
2.数据可视化是数据科学项目中普遍应用的技术。Matplotlib是用途广泛且历史悠久的数据可视化工具,其官方网站是https://matplotlib.org/。建议读者熟练掌握此工具的基本应用方法。
1.1.3 图像文件
图像文件很常见,“它里面也保存了数据吗?”
通常,图像可以分为“位图”和“矢量图”两类。文件扩展名为“.jpg”“.jif”“.png”的图像文件是位图;文件扩展名为“.swf”“.pdf”“.svg”的是矢量图。位图由很多点组成(称为“点阵”,点就是像素),每个点以0~255之间的整数表示一种灰度级别,不同的灰度级别代表了红、绿、蓝(RGB)的比例,即表示了一种颜色。矢量图记录的是绘制图像的方法,不是点阵数据,方法中包含了点的坐标值和填充颜色的值等信息。本书下述内容只讨论位图。
基础知识
在Python语言生态中,Pillow是常用的图像处理库(Python Imaging Library,PIL),具有强大的图像处理功能,其官方网站是https://pillow.readthedocs.io/。Pillow的基本安装方法如下:
利用上述方式安装,可能因为本地缺少某些依赖程序而无法执行Pillow。如果遇到此类情况,可先参考官方网站及报错信息,然后安装或者升级所缺乏的工具。
很多工具包依赖其他程序。用pip安装,通常会自动检查并安装各种依赖程序。若遇到例外,则需要单独安装。
安装完成之后,用下面的方式实现从本地读取图像文件的操作。
In[16]的代码块中引入了Pillow包中的Image模块(如⑯所示),并用此模块的open函数读入一个图像文件(如⑰所示)。⑰是惰性操作,虽然文件已被打开,但数据并未被从文件中读取到内存,直到执行后续操作。
读入的彩色图像可以转化为黑白的(灰度图像)。
对图像的处理是数据科学的一个重要方向。
In[16]和In[17]得到的是Image类型的实例对象,它具有Numpy的数组接口,因此能够执行In[18]中的操作。
当图像文件被读入之后,就可以将其转化为Numpy的数组类型(也可以转化为矩阵类型)。
In[16]读入的图像高为407px(像素)、宽为396px,上面显示的不论是彩色图像还是黑白图像所对应的数组都要有两个维度对应于图像的高和宽,只是彩色图像又多出一个维度。
对图像文件的操作,还有另外一个更常用的库OpenCV,其官方网站:https://opencv.org/。安装方法如下:
各种工具包的官方网站都有较详细的安装和使用说明,请务必认真阅读。
下面演示如何使用OpenCV读取图像文件。
In[20]利用OpenCV(⑱引入的模块)的imread函数读入了图像文件,其中第2个参数用0表示将读入的文件灰度化(转化为黑白图像)。从结果可知,读入文件之后所得对象是数组类型的对象。要想再次显示该图像,可进行如下操作:
In[21]将表示图像文件的数组对象转化为图像,并显示到当前的Jupyter浏览器中。此功能还可以使用In[16]代码块中引入的Image模块实现:
在Python中,读入图像文件的方式不止以上两种,我们已经反复应用的matplotlib也具有此功能。
项目案例
1.项目描述
先读取一个图像文件,然后完成如下操作:
●截取图像的一部分并显示。
●对得到的黑白图像进行翻转,并显示翻转后的效果。
2.实现过程
截取图像表现在对数组的操作上就是“切片”。先简单了解数组的切片操作:
“切片”是数组、DataFrame对象的重要操作。
更详细的“数组切片”知识,请参阅《跟老齐学Python:数据分析》的第1章内容。
下面演示如何用“切片”操作实现“截图”。
In[26]中的img是形状为(407, 396)的二维数组(见In[19]、In[20]),“50: 260”表示对数组沿0轴方向切片,表现在图像上为纵向截图;“100: 280”表示沿1轴方向切片,在图像上为横向截图。最终得到了Out[26]的结果。
如果“翻转”图像,可以通过数组的运算实现。
思考:在“255 - img”中为什么使用255?可以使用其他数字吗?
现在广泛使用数码照相技术,此前的相机主要用“胶卷”成像。这种“底片”在医院能见到。
“翻转”之后显示了“底片”效果,实现方式就是执行了⑲的运算。
动手练习
1.除了“基础知识”中所演示的读入图像文件的方法,还有很多其他途径,比如matplotlib也提供了实现此操作的方法。请参考matplotlib的官方文档和其他有关资料,编写读取图像文件的程序。
2.自选两幅图像文件,并利用“项目案例”中所演示的“截图”方法,各在两幅图中截取一部分,然后合并为一幅图并显示。
“图的合并”就是数组的连接/合并,可以使用pd.concat、pd.merge,两者的区别请读者参阅《跟老齐学Python:数据分析》。
扩展探究
1.在In[26]中,利用OpenCV读取了彩色的图像文件之后,将其转化为灰度格式(黑白图)。函数imread的完整形式是:
flags表示图像文件的加载模式。请查阅有关资料,回答如下问题:
●OpenCV中的图像文件都有哪些加载模式?参数flags的可取值及相应的含义是什么?
●读入彩色文件并显示。对比颜色是否与原来的一致?如果不一致,是什么原因造成的?
2.参考《跟老齐学Python:数据分析》的第1章,全面理解数组的切片、连接、分割等基本操作。