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 处理逻辑重)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"(默认就是,但显式写上更安心)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 严格一致。字段顺序、字节序、空值编码,一个不对就全崩。