5.1 读写文件
本节主要介绍读写各种格式的文件,其中除了对文件的操作,也有大量对数据格式及用途的说明。例如,从服务中返回的数据虽然不是文件,但是也有大量Json或XML格式的数据,本节将介绍这些数据的格式、解析及构造的方法。
5.1.1 读写文本文件
下面介绍最常用的读写文本文件的方法,文本文件的扩展名一般为“.txt”。
1.写入文件
使用open函数以写入“w”的方式打开文件,常用的写入方法有两种:write函数为写入一个字符串;writelines函数为写入一个序列的字符串,至于换行与否主要取决于字符串尾部的“\n”回车符。在写入并调用close函数关闭文件之后,文件内容才能被完整保存。
2.读取文件全部内容
如果被读取的文件涉及中文则需要注意字符集,在Linux系统中的文件大多数使用Utf-8字符集,而在Windows系统中创建的文件一般使用GBK/GB2312/GB18030字符集。在本例中,使用read和readlines两种方法读取文件的全部内容(注意每次只能使用其中一种)。
read方法将文件的全部内容作为一个字符串返回,readlines方法将文件中每一行作为一个字符串,并返回字符串序列。
3.按行读取文件
如果文件过大,一次性装载需要占用大量内存,则建议使用单行readline方法读取。
5.1.2 写日志文件
日志文件是记录程序操作和事件的记录文件或记录文件的集合,一般由程序开发人员编写,开发和运维人员共同使用。开发人员通过日志可以调试程序;运维人员通过日志检查程序近期是否正常运行,如果出现异常,则可以通过日志快速定位问题。
因此,用日志记录程序流程、事件,以及异常时的详细信息非常重要,尤其是对部署在客户场地的程序。另外,日志有时也记录用户操作、程序运行地理位置等跟踪信息,用于后台的用户研究和数据挖掘。
日志文件一定要详细、清晰且具有较高的可读性,以便减少开发与运维人员后期的沟通成本。由于我们有时也使用程序来检测和分析日志,因此,定义关键字和格式也很重要。
Python使用logging工具管理日志,日志可以在终端显示,也可以记录成文件。每条日志都用级别号标志其严重程度,一般通过级别过滤选择性地记录和显示日志,级别定义如表5.1所示。
表5.1 logging信息分级信息
本例展示了以屏幕输出和文件输出两种方式记录日志信息,日志文件为当前目录下的log.txt,格式为文本文件。
例程中设置了三次日志级别:第一次对程序中所有日志设置,级别为DEBUG,即显示全部日志;第二次设置日志文件的级别为INFO,将INFO和INFO以上的日志记录在文件中;第三次是设置屏幕显示日志级别为WARNING,相当于先用第一次设置的DEBUG过滤一遍,再用WARNING过滤一遍,最终输出的是WARNING及以上的日志信息。
需要注意的是,程序用addHandler函数添加了两个句柄:一个用来显示输出,另一个用来记录日志文件。之后输出的log信息会通过句柄调用对应的输出,如果同一个输出addHandler多次,又没有removeHandler,则同一条日志就会被记录多次。因此,注意不要重复调用,尤其是在用Jupyter Notebook调试时,不要重复运行该代码段。
5.1.3 读写XML文件
操作XML文件有SAX和DOM两种方法:SAX是Simple API for XML的简称,以逐行扫描的方式解析XML,常用于读写大型文件,解析速度较快,但只能顺序访问文件内容;DOM是Document Object Model的简称,是以对象树来描述一个XML文档的方法,用于解析中小型XML文件,速度较慢,但可以随机访问节点,使用方便。
在数据处理中,XML文件一般存储相对简单的数据,内容不会非常多而复杂,使用DOM方式就能实现绝大部分的功能。另外,HTML也是XML的一种,用DOM方法也可以构建网页。本例将介绍用简单的DOM方法构建和解析XML文件的方法。
XML的两个重要概念是元素Element和节点Node,其中XML文档中每个成分都是节点,每个XML标签TAG是一个元素节点(Element node),包含在XML元素中的文本是文本节点(Text node)。另外,还有属性节点、注释节点等,整个文档也是一个大节点。元素节点是信息的容器,也可能包含其他元素节点,如文本节点、属性节点等。元素一般是成对出现的。
本小节将利用Python的minidom库,用两段代码示例分别展示生成XML文件和解析XML文件。下例为生成XML文件:
程序生成如下XML文件:
以下代码是从上面生成的XML文件中读取的数据,其中有对节点和元素的操作以及对属性的操作。在解析XML文件时,最常用的两个方法是按标签名称查找元素getElementsByTagName和列出子节点childNodes。
从调用方法可知,<addr></addr>是元素节点,attr是标签,而其中的字符串内容“https://blog.csdn.net/xieyan0811”是文本节点,不是元素。
5.1.4 读写Json文件
Json是一种轻量级的数据交换格式,是独立于编程语言的文本数据。其清晰的语法和简捷的层次结构对于编程人员来说可读性强,对于机器来说方便编解码。另外,其编码简单,也有效地提高了传输效率。Json常用于网络服务端与客户端之间的数据传输,有时也用于简单的数据存储。
本例中展示了对Json字符串的操作:第一部分利用Json库的loads函数和dumps函数在数据结构和字符串之间转换,利用dumps的indent参数生成带换行和缩进的Json字符串。
第二部分展示了读写Json文件的方法,可以看到组成数据的字典和序列都是Python的基本元素,因此利用该方法也可以把Python的简单数据序列化存储到Json文件中。需要注意的是,Python的字典和Json有些差异,如Json的关键字只能是字符串,本章后几节将介绍更多Python结构化数据的存储方法。
5.1.5 读写CSV文件
CSV是Comma-Separated Values(逗号分隔值)的缩写,是一种以纯文本格式存储的数据文件,每个记录占一行,字段之间一般用逗号分隔(也可以指定其他字符分隔),用Excel软件可以读写CSV文件。
很多数据比赛和示例中的数据都使用CSV格式存储。相对于二进制文件,纯文本文件在不使用其他工具的情况下也能查看内容,方便查找和编辑。但相对于Excel,CSV只能存储文本格式的数据,不支持指定各字段的数据类型,没有多个工作表,不能插入图片,无法设置单元格颜色、宽度等属性;相对于PKL文件,由于它与Python内部存储格式不一致,因此在读写大文件时编解码需要较长的时间。尽管如此,它仍是中等及以下量级数据保存及交换的首选存储格式。
推荐使用Pandas的DataFrame提供的方法读取数据文件,DataFrame是数据分析中最常用的数据组织方法。本例的第一部分展示写入CSV文件的方法,需要注意常用的参数:Index控制是否将索引信息写入文件,默认值是True,但一般选择不写入;header控制是否将字段名(即表头)写入文件,一般使用默认值True;columns指定在写入CSV时包含哪些字段及字段顺序。
程序的第二部分用于从CSV读出数据并通过info函数显示数据的基本信息。从第一部分的info输出可以看到,由于写入的数据都是字符,因此被识别为Object对象类型,而在通过存储和读取的操作后,字段Age变成了int类型。这是因为CSV并不存储数据类型信息,在数据被读出时,该列的值都是整型,所以整个字段被识别为int类型。
5.1.6 读写PKL文件
PKL是Python保存数据的文件格式,不仅能保存数据表,还能保存字符串、字典、列表等类型的数据,是Python将对象持久化到本地的一般方法。其优点是存储了数据类型信息并且读写的速度快;缺点是以二进制格式存储,不能直接查看其内容,与CSV文件相比,占用空间更大。
需要注意的是,Python 2与Python 3的PKL文件格式不同。由于使用Python 3编码的PKL文件无法被Python 2正常读取,因此,需要保证读写程序Python版本的一致性。
下面展示三个PKL例程:第一个例程使用DataFrame提供的方法对PKL文件读写数据表;第二个例程用PKL文件存取Python的其他类型数据;第三个例程用PKL文件存储机器学习模型。
第一个例程使用的数据表与5.1.5节CSV中的数据表内容一致,不同的是,通过PKL存储后数据类型不变。因此,如果想要保持数据类型,则推荐PKL存储。
第二个例程直接使用pickle库存取数据,示例中使用了字典、列表以及多种字符和数值类型,使用dump函数和load函数存取。
第三个例程介绍了用joblib方式存取PKL文件。joblib是机器学习库Sklearn的一个子模块,常用它来存储机器学习模型,即训练之后保存模型文件,而在预测时加载文件直接使用,在大数据量时,这使joblib比普通pickle更高效。本例中使用鸢尾花数据集训练分类模型,然后把模型存入PKL文件,再从文件读出模型进行数据预测。
5.1.7 读写HDF5文件
HDF5是Hierarchical Data Format 5的简称,是一种高效的层次存储数据格式,当前为第5个版本。很多深度学习的模型都用该格式存储,下面我们了解一下操作HDF5文件的基本方法。
首先,安装hdf5库:
安装过程中可能会报错:fatal error:hdf5.h:No such file or directory,这是由于未安装HDF5的底层依赖包所导致的,可从网站下载源码包编译安装,或者下载可执行程序安装包(bin包),解压后设置环境变量。
之后再运行pip install即可正常安装。HDF5文件以Key,Value的方式存储数据,下面给两个Key主键分别赋值成不同维度的数组后保存成HDF5格式文件。
从文件读出数据并遍历其所有Key主键,且显示其名称、形状及具体值。从程序运行结果可以看出,HDF5文件完整地保存了所有值及其数据结构。
Pandas也提供了HDFStore方法支持HDF5格式。
5.1.8 读写Excel文件
Excel文件是MicroSoft Excel的文件存储格式,其2003以下版本使用XLS格式存储,是一种特定的复合文档结构;2003以上版本默认为XLSX存储,使用基于XML的压缩格式存储。
Excel文件一般由人工编辑,支持Sheet页、输入图片、显示格式、各种数据类型定义等,但是在做数据分析时,很少用到这些,重视的是显示和打印效果,很少把每个字段的类型都按规则设置。Excel还有一些行数限制,如2003版最大行数是65536行,2007版为1048575行。在数据量很大的情况下,一般使用数据库存储。
综上所述,Excel文件主要保存的是个人的数据表格,一般是手工编辑生成的。在做小数据量数据分析时,客户一般以Excel文件的形式提供数据。由于Excel文件比较复杂,读写速度比CSV还慢很多,因此,在通常情况下,数据分析中不使用该格式保存和交换数据,而是多用于和客户数据的对接。
本例中主要介绍读写Excel表格的方法、对Sheet页的读取以及对应的Python库。虽然Pandas中有to_excel方法,但由于其仍需要底层Excel库的支持,因此第一步先安装支持XLS和XLSX两种文件格式的Python支持库。
用Pandas提供的方法读写简单的Excel文件。
使用openpyxl库遍历各个Sheet页,并按行列读取内容。