You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何快速读取包含列表嵌套结构的大型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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:40:13