一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何解决Python中NumPy读取大型CSV文件速度慢的难题

时间:2026-07-13 09:08:46 编辑:袖梨 来源:一聚教程网

numpy.loadtxt读大CSV卡住是因为它是纯Python实现,逐行解析、无底层优化、全量加载且不支持分块或列筛选;应改用pandas.read_csv配合to_numpy(),或预转换为二进制格式后用np.memmap加载。

为什么 numpy.loadtxt 读大 CSV 会卡住?

因为 numpy.loadtxt 是纯 Python 实现的文本解析器,逐行扫描、类型推断、内存预分配全靠解释器跑,没做底层优化。100MB 以上 CSV 基本就明显变慢,500MB+ 可能 OOM 或卡死几分钟。

它默认把整张表一次性加载进内存,且不支持分块、跳过列、指定 dtype——哪怕你只要第 3 列,它也得把每行所有字段都 parse 一遍。

  • 不支持缺失值快速跳过(nan 处理逻辑重)
  • 不能跳过注释行以外的任意行(比如 header 后面还有统计行)
  • 无法限制读取行数用于调试(max_rows 是 NumPy 1.23+ 才加的,旧版本没有)

numpy.genfromtxt 也没快多少?试试这些参数

genfromtxt 虽然比 loadtxt 多些灵活性,但默认行为依然保守。关键不是换函数,而是关掉它“过度负责”的部分:

  • 显式传 dtype,比如 dtype="float32",避免自动推断开销
  • skip_header=1 而不是依赖 comments="#" 去逐行判断
  • usecols=(0, 2, 4) 只加载需要的列,跳过字符串列或 ID 列
  • invalid_raise=False 避免遇到坏数据就中断再重试

示例:

np.genfromtxt("data.csv", delimiter=",", dtype="float32", usecols=(1,3), skip_header=1)

立即学习“Python免费学习笔记(深入)”;

真正提速:改用 pandas.read_csv + to_numpy()

NumPy 本身不擅长 IO,这是 Pandas 的强项。Pandas 底层用 C 解析(libc + csv-parser),支持多线程、内存映射、chunking,且类型推断更智能。

别直接转成 list 再喂给 np.array(),那会丢掉零拷贝优势:

  • pd.read_csv(..., dtype={"col1": "float32"}) 控制列类型
  • engine="c"(默认就是,但显式写上更安心)
  • 需要纯 NumPy 数组时,直接调 df.to_numpy(dtype="float32"),不是 np.array(df)
  • 超大文件可配合 chunksize=10000 分批处理,避免内存峰值

极端场景:内存不够?试试 numpy.memmap + 自定义 parser

当文件大到连 Pandas 都吃不下(比如 >20GB),又必须用 NumPy 原生接口时,memmap 是唯一可行路径——但它不支持 CSV,只认二进制格式。

做法是先用一次 Pandas 或 Dask 把 CSV 转成紧凑的 .npy.bin(比如 float32 连续存储),再用 np.memmap 加载:

arr = np.memmap("data.bin", dtype="float32", mode="r", shape=(10_000_000, 5))

注意:memmap 不会自动处理 CSV 的行列对齐、缺失值、类型混合——这些必须在转换阶段完成,漏一步,后面读出来全是错的。

真正难的不是读,是保证二进制格式和原始 CSV 的 schema 严格一致。字段顺序、字节序、空值编码,一个不对就全崩。

热门栏目