使用Python读取大文件的方法


Posted in Python onFebruary 11, 2018

背景

最近处理文本文档时(文件约2GB大小),出现memoryError错误和文件读取太慢的问题,后来找到了两种比较快Large File Reading 的方法,本文将介绍这两种读取方法。

准备工作

我们谈到“文本处理”时,我们通常是指处理的内容。Python 将文本文件的内容读入可以操作的字符串变量非常容易。文件对象提供了三个“读”方法: .read()、.readline() 和 .readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而.read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。下面是read()方法示例:

try:
f = open('/path/to/file', 'r')
print f.read()
finally:
if f:
f.close()

调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。

如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便:

for line in f.readlines():
process(line) #

分块读取

处理大文件是很容易想到的就是将大文件分割成若干小文件处理,处理完每个小文件后释放该部分内存。这里用了iter 和 yield:

def read_in_chunks(filePath, chunk_size=1024*1024):
"""
Lazy function (generator) to read a file piece by piece.
Default chunk size: 1M
You can set your own chunk size
"""
file_object = open(filePath)
while True:
chunk_data = file_object.read(chunk_size)
if not chunk_data:
break
yield chunk_data
if __name__ == "__main__":
filePath = './path/filename'
for chunk in read_in_chunks(filePath):
process(chunk) # <do something with chunk>

使用With open()

with语句打开和关闭文件,包括抛出一个内部块异常。for line in f文件对象f视为一个迭代器,会自动的采用缓冲IO和内存管理,所以你不必担心大文件。

代码如下:

#If the file is line based
with open(...) as f:
for line in f:


process(line) # <do something with line>

优化

面对百万行的大型数据使用with open 是没有问题的,但是这里面参数的不同也会导致不同的效率。经过测试发先参数为"rb"时的效率是"r"的6倍。由此可知二进制读取依然是最快的模式。

with open(filename,"rb") as f: 
  for fLine in f: 
  pass

测试结果:rb方式最快,100w行全遍历2.9秒。基本能满足中大型文件处理效率需求。如果从rb(二级制读取)读取改为r(读取模式),慢5-6倍。

结论

在使用python进行大文件读取时,应该让系统来处理,使用最简单的方式,交给解释器,就管好自己的工作就行了。同时根据不同的需求可以选择不同的读取参数进一步获得更高的性能。

Python 相关文章推荐
Python不规范的日期字符串处理类
Jun 10 Python
详解Python设计模式编程中观察者模式与策略模式的运用
Mar 02 Python
Python实现代码统计工具(终极篇)
Jul 04 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
Feb 08 Python
PyQt5每天必学之单行文本框
Apr 19 Python
在Django中输出matplotlib生成的图片方法
May 24 Python
PyTorch CNN实战之MNIST手写数字识别示例
May 29 Python
在python中使用requests 模拟浏览器发送请求数据的方法
Dec 26 Python
Python filter()及reduce()函数使用方法解析
Sep 05 Python
用Python进行websocket接口测试
Oct 16 Python
用Python实现童年贪吃蛇小游戏功能的实例代码
Dec 07 Python
Python开发五子棋小游戏
Apr 28 Python
python脚本作为Windows服务启动代码详解
Feb 11 #Python
分析Python读取文件时的路径问题
Feb 11 #Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 #Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
Feb 11 #Python
代码讲解Python对Windows服务进行监控
Feb 11 #Python
django 按时间范围查询数据库实例代码
Feb 11 #Python
python实现媒体播放器功能
Feb 11 #Python
You might like
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
LotusPhp笔记之:Logger组件的使用方法
2013/05/06 PHP
php通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
2012/01/15 Javascript
自己写了一个展开和收起的多更能型的js效果
2013/03/05 Javascript
详解ES6中的let命令
2020/04/05 Javascript
jQuery实现限制文本框的输入长度
2017/01/11 Javascript
学习使用Bootstrap页面排版样式
2017/05/11 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
基于daterangepicker日历插件使用参数注意的问题
2017/08/10 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
vue项目中在外部js文件中直接调用vue实例的方法比如说this
2019/04/28 Javascript
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
[03:40]DOTA2英雄梦之声_第01期_炼金术士
2014/06/23 DOTA
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
python中如何使用朴素贝叶斯算法
2017/04/06 Python
Numpy 将二维图像矩阵转换为一维向量的方法
2018/06/05 Python
Python中实例化class的执行顺序示例详解
2018/10/14 Python
使用Python 统计高频字数的方法
2019/01/31 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
浅谈pytorch grad_fn以及权重梯度不更新的问题
2019/08/20 Python
Django认证系统user对象实现过程解析
2020/03/02 Python
Selenium 滚动页面至元素可见的方法
2020/03/18 Python
解决python3.x安装numpy成功但import出错的问题
2020/11/17 Python
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
您的时尚,您的生活方式:DTLR Villa
2019/12/25 全球购物
新奥尔良珠宝:Mignon Faget
2020/11/23 全球购物
工程承包协议书
2014/04/22 职场文书
社会调查研究计划书
2014/05/01 职场文书
航空学院求职信
2014/06/11 职场文书
英语专业自荐书
2014/06/13 职场文书
乡镇党员干部四风对照检查材料思想汇报
2014/09/27 职场文书
基层组织建设年活动总结
2015/05/09 职场文书
运动会通讯稿200字
2015/07/20 职场文书
公司晚会主持词
2019/04/17 职场文书