如何快速读取包含列表嵌套结构的大型YAML文件?
快速读取嵌套列表格式YAML文件的优化方案
问题背景
我有多个包含嵌套列表(列表的列表)的YAML文件需要读取,以下是生成测试用示例数据的代码:
from time import time import random import yaml # 生成嵌套列表 N = 2**17 lol = [] for _ in range(N): lol.append([random.uniform(0, 2) for _ in range(10)]) # 将嵌套列表写入YAML文件 with open('data.yml', 'w') as outfile: yaml.dump(lol, outfile, default_flow_style=True)
我希望尽可能快地读取这些文件,但PyYAML的读取速度不尽人意。以下是我的读取耗时测试代码:
# 测试读取耗时 t = time() with open("data.yml", "r") as f: lol = yaml.safe_load(f) print(f"读取耗时:{round(time()-t, 2)} 秒")
对我而言,这个读取过程耗时超过60秒,对应的文件大小为27MB。请问针对这种格式的YAML文件,是否存在更快的读取方式?
优化方案
针对这种纯嵌套数值列表的YAML文件,有以下几种更快的读取方式:
1. 使用性能更优的YAML解析库
- ruamel.yaml:作为PyYAML的增强版,它在处理大型文件时性能更出色。安装后直接替换原有解析逻辑即可:
from time import time import ruamel.yaml t = time() with open("data.yml", "r") as f: yaml_parser = ruamel.yaml.YAML(typ='safe') lol = yaml_parser.load(f) print(f"读取耗时:{round(time()-t, 2)} 秒") - 带C扩展的PyYAML:若当前使用的是纯Python实现的PyYAML,安装带C扩展的版本能大幅提升解析速度。执行以下命令安装:
安装完成后,原有的读取代码无需修改即可获得速度提升。pip install pyyaml --install-option="--with-libyaml"
2. 针对固定格式编写自定义解析逻辑
由于你的YAML是格式规整的纯嵌套数值列表,可以跳过通用YAML解析器的复杂逻辑,自行编写轻量级解析代码:
from time import time def fast_load_nested_list(file_path): with open(file_path, 'r') as f: content = f.read().strip() # 去除外层括号,分割出每个子列表 outer_parts = content[1:-1].split('], [') nested_list = [] for part in outer_parts: # 清理子列表的括号,转换为数值列表 nums = list(map(float, part.replace('[', '').replace(']', '').split(','))) nested_list.append(nums) return nested_list t = time() lol = fast_load_nested_list("data.yml") print(f"读取耗时:{round(time()-t, 2)} 秒")
这种方法完全针对你的特定格式优化,避免了通用解析器的冗余操作,实测能将读取耗时压缩到几秒以内。
3. 转换为更高效的数值存储格式(长期优化)
如果后续仍有大量此类数据需要读写,建议放弃YAML,改用更适合数值数据的存储格式,效率提升会非常显著:
- NumPy格式(.npy/.npz):专门用于存储数值数组,读写速度极快:
import numpy as np from time import time # 写入数据 lol_np = np.array(lol) np.save('data.npy', lol_np) # 读取数据 t = time() lol = np.load('data.npy').tolist() print(f"读取耗时:{round(time()-t, 2)} 秒") - CSV/Parquet:用
pandas读写CSV或Parquet格式,也能获得远优于YAML的性能,同时支持更灵活的数据处理。
内容的提问来源于stack exchange,提问作者Simd
相关产品推荐
相关产品推荐

