一、仅用pd加载大文件(iterator、chunksize)
要使用Pandas进行高效加载超大文件,我们通常会利用其内置的分块(chunk)处理功能。不过,请注意,Pandas本身并不支持多线程读取文件;它更倾向于单线程中进行块处理。尽管如此,对于优化加载超大文本文件这一场景,可以通过以下方式实现提速:
- 预先知道或估计每个数据块的行数或大小。
- 利用
pandas.read_csv
等方法的chunksize
参数来迭代读取数据。- 使用多进程而非多线程来并行处理每一块数据(如果确实需要并发执行),因为Python中GIL(全局解释器锁)限制了同一时刻只能有一个线程执行Python字节码。
下面是一个示例代码。请注意,在此示例中没有直接采用多进程来读取文件分片。相反,我们首先以流式模式逐步载入小数据块,并在必要时可应用某种形式的并行处理框架(如Dask)针对这些已经被逐步载入内存中DataFrame对象进行后续操作。
import pandas as pd
class EfficientTextLoader:
"""
采用pandas高效加载超大文本文件
"""
def __init__(self, filepath, chunksize=10000):
"""
初始化
:param filepath: 文件路径
:param chunksize: 每次迭代加载的行数,默认设定为10000条记录/行
注意:根据你系统和硬件配置调整chunksize大小以获得最佳性能。
较小值减少内存消耗但增加I/O频率;较大值则反之。
"""
self.filepath = filepath
# Pandas 从版本0.24 开始支持 TextFileReader 属性 'chunksize'.
# 当使用 read_csv 等函数与 'iterator=True' 结合时,
# 设置 'chunksize' 可返回 TextFileReader 对象供迭代.
self.chunk_size = chunksize
def load(self):
"""按照指定chunks逐渐地、有效地装载整个文档"""
reader = pd.read_csv(self.filepath,
sep='\t', # 假设是制表符分隔的TXT 文档;根据需求而定
iterator=True,
header=None,
chunksize=self.chunk_size) # 逐行加载
chunks = []
try:
while True:
chunks.append(next(reader))