如何分块加载Pickle文件?是否有其他Python原生文件分块加载方案?
分块加载Pickle文件及Python原生格式的可行方案
当然可以分块加载Pickle文件!不过和CSV按行分块的逻辑不太一样,因为Pickle是二进制序列化格式,它是把整个Python对象打包存储的,所以得从保存阶段或者读取时的文件操作技巧入手。下面给你几种可行的方案,还有其他Python原生格式的选项:
1. 提前分块保存Pickle文件(最稳妥的方案)
如果在保存数据时就考虑到后续要分块加载,直接把大数据集拆分成多个小的Pickle文件是最省心的方式。比如把数据按固定大小切分,分别存成data_part_0.pkl、data_part_1.pkl这样的文件,读取时再逐个加载合并。
示例代码:
import pickle import numpy as np # 模拟一个大数据集 big_dataset = np.random.rand(1_000_000) chunk_size = 100_000 # 每个块的大小 # 分块保存 for idx in range(0, len(big_dataset), chunk_size): chunk = big_dataset[idx:idx+chunk_size] with open(f'data_part_{idx//chunk_size}.pkl', 'wb') as f: pickle.dump(chunk, f) # 分块加载 loaded_chunks = [] for idx in range(0, len(big_dataset), chunk_size): with open(f'data_part_{idx//chunk_size}.pkl', 'rb') as f: chunk = pickle.load(f) loaded_chunks.append(chunk) # 合并所有块 full_dataset = np.concatenate(loaded_chunks)
2. 单文件分块读取(利用多次dump/load)
如果已经有一个单个的大Pickle文件,只要它是通过**多次调用pickle.dump()**写入的(而不是一次性dump整个大对象),就能循环调用pickle.load()来分块读取,直到遇到文件结束符。
示例代码:
import pickle import numpy as np big_dataset = np.random.rand(1_000_000) chunk_size = 100_000 # 把多个块写入同一个Pickle文件 with open('single_file_chunks.pkl', 'wb') as f: for idx in range(0, len(big_dataset), chunk_size): chunk = big_dataset[idx:idx+chunk_size] pickle.dump(chunk, f) # 分块读取这个单文件 loaded_chunks = [] with open('single_file_chunks.pkl', 'rb') as f: while True: try: chunk = pickle.load(f) loaded_chunks.append(chunk) except EOFError: # 读取到文件末尾,退出循环 break full_dataset = np.concatenate(loaded_chunks)
⚠️ 注意:如果你的大Pickle文件是一次性dump整个对象生成的(比如直接pickle.dump(big_dataset, f)),那没办法分块读取——因为Pickle需要完整解析整个序列化对象才能加载,这种情况下只能先完整加载再拆分处理。
3. 其他Python原生格式的分块选项
除了Pickle,还有几个Python生态里的原生/常用工具支持分块处理大数据:
- Joblib:专门为数值型大数据优化,比Pickle更高效,支持内存映射加载(不用一次性把数据读进内存)。
from joblib import dump, load # 保存大数组 dump(big_dataset, 'big_data.joblib', compress=3) # 分块加载(内存映射模式,按需读取数据) loaded_dataset = load('big_data.joblib', mmap_mode='r') - Dill:扩展了Pickle的能力,可以序列化更多Python对象(比如自定义类、闭包等),用法和Pickle完全兼容,同样支持多次dump/load实现分块读写。
- Pandas分块处理:如果你的数据是Pandas DataFrame,虽然
pd.read_pickle默认不支持chunksize,但可以先把DataFrame拆分成多个小分块分别存成Pickle文件,再逐个读取合并;或者用Pandas支持的feather/parquet格式(虽然不是纯Python原生,但Pandas原生支持),这两种格式天然支持分块读写。
内容的提问来源于stack exchange,提问作者Naren Babu R
相关产品推荐
相关产品推荐

