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

如何读取超内存的大型Numpy数组文件并正确提取1/4数据?

Numpy大体积npy文件部分读取解决方案

错误原因分析

  • 直接调用np.memmap读取npy文件的方式是错误的:标准npy文件包含固定长度的文件头,存储了原数组的shape、dtype、存储顺序等元信息,你手动指定shape和dtype读取时,会把文件头内容当做数组数据解析,自然会出现数值异常、形状不匹配的问题。
  • 修改dtype后数值变化是正常现象:不同dtype对应的单元素字节长度、解析规则完全不同,比如原数组是单字节的uint8类型,你用4字节的int32读取时,会把连续4个uint8的字节拼接为1个int32数值,结果必然和原数据不符。

正确操作步骤

方法1:使用np.load自带的内存映射模式(推荐)

Numpy原生的np.load接口支持直接以内存映射模式加载npy文件,会自动解析文件头,不需要手动指定元信息,用法最简单:

# 以只读内存映射模式加载文件,不会将全量数据读入内存
arr = np.load("dataset/b.npy", mmap_mode='r')
# 查看原数组的实际形状、数据类型,确认无误
print(arr.shape, arr.dtype)
# 提取1/4数据,示例沿第一维(样本维度)取前1/4,按需读取不会加载全量数据
# 可根据需求自行调整切片规则
subset = arr[: arr.shape[0] // 4]
# 如果需要保存提取的子集到新文件
np.save("dataset/subset_b.npy", subset)

方法2:手动解析文件头后使用np.memmap

如果你需要直接使用np.memmap接口,需要先解析npy文件头拿到偏移量、元信息后再创建memmap对象:

import numpy as np

# 第一步:解析npy文件头,获取元信息和数据偏移量
with open("dataset/b.npy", "rb") as f:
    # 读取npy文件魔数
    magic = np.lib.format.read_magic(f)
    # 根据版本读取数组头
    if magic[0] == 1:
        shape, dtype, fortran_order = np.lib.format.read_array_header_1_0(f)
    else:
        shape, dtype, fortran_order = np.lib.format.read_array_header_2_0(f)
    # 数据段起始偏移量
    data_offset = f.tell()

# 第二步:创建正确的memmap对象
arr = np.memmap(
    "dataset/b.npy",
    mode="r",
    dtype=dtype,
    shape=shape,
    offset=data_offset
)

# 后续提取子集的操作和方法1一致
subset = arr[: arr.shape[0] //4]

内容的提问来源于stack exchange,提问作者devesh marwah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:15:02