如何在磁盘上直接创建numpy .npy文件?

13 投票
2 回答
6948 浏览
提问于 2025-04-16 07:56

有没有办法在不先在内存中分配相应数组的情况下创建一个 .npy 文件?

我需要创建并处理一个很大的 numpy 数组,这个数组太大了,无法在内存中创建。Numpy 支持内存映射,但根据我所了解,我的选择有两个:

  1. 使用 numpy.memmap 创建一个内存映射文件。这种方法直接在硬盘上创建文件,而不分配内存,但它不存储一些元数据,所以当我稍后重新映射这个文件时,我需要知道它的数据类型、形状等。下面的例子中,如果不指定形状,内存映射会被解释为一维数组:

    In [77]: x=memmap('/tmp/x', int, 'w+', shape=(3,3))
    
    
    In [78]: x
    Out[78]: 
    memmap([[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]])
    
    
    In [79]: y=memmap('/tmp/x', int, 'r')
    
    
    In [80]: y
    Out[80]: memmap([0, 0, 0, 0, 0, 0, 0, 0, 0])
    
  2. 在内存中创建一个数组,使用 numpy.save 保存它,然后可以以内存映射模式加载。这种方法会把数组数据和元数据一起记录在硬盘上,但至少需要先为整个数组分配一次内存。

2 个回答

5

正如你自己发现的,NumPy主要是用来处理内存中的数据。对于硬盘上的数据,有不同的库可以使用,现在最常用的可能是HDF5。我建议你看看h5py,这是一个很棒的Python库,可以用来操作HDF5。它是为了和NumPy一起使用而设计的,如果你已经会用NumPy,学习这个库的接口会很简单。想了解它是如何解决你问题的,可以看看数据集的文档

为了完整性,我还得提一下PyTables,它似乎是处理Python中大数据集的“标准”方式。我没有使用它,因为我觉得h5py更吸引我。这两个库都有常见问题解答,说明了它们各自的特点和区别。

13

我也有过同样的问题,看到Sven的回复时感到有些失望。因为如果不能把一个很大的数组存到文件里,然后分块处理,那numpy就会失去一些重要的功能。你的情况似乎和最初设计.npy格式的理由很相似(可以参考这个链接:http://svn.scipy.org/svn/numpy/trunk/doc/neps/npy-format.txt)。

后来我发现了numpy.lib.format,这里面似乎有很多有用的功能。我不明白为什么这些功能在numpy的主包里没有提供。相比HDF5的一个主要优点是,这个功能是和numpy一起提供的。

>>> print numpy.lib.format.open_memmap.__doc__

"""
Open a .npy file as a memory-mapped array.

This may be used to read an existing file or create a new one.

Parameters
----------
filename : str
    The name of the file on disk. This may not be a filelike object.
mode : str, optional
    The mode to open the file with. In addition to the standard file modes,
    'c' is also accepted to mean "copy on write". See `numpy.memmap` for
    the available mode strings.
dtype : dtype, optional
    The data type of the array if we are creating a new file in "write"
    mode.
shape : tuple of int, optional
    The shape of the array if we are creating a new file in "write"
    mode.
fortran_order : bool, optional
    Whether the array should be Fortran-contiguous (True) or
    C-contiguous (False) if we are creating a new file in "write" mode.
version : tuple of int (major, minor)
    If the mode is a "write" mode, then this is the version of the file
    format used to create the file.

Returns
-------
marray : numpy.memmap
    The memory-mapped array.

Raises
------
ValueError
    If the data or the mode is invalid.
IOError
    If the file is not found or cannot be opened correctly.

See Also
--------
numpy.memmap
"""

撰写回答