【问题标题】:How can I create a numpy .npy file in place on disk?如何在磁盘上创建一个 numpy .npy 文件?
【发布时间】:2011-05-19 03:06:22
【问题描述】:

是否可以在不先在内存中分配对应数组的情况下创建.npy文件?

我需要创建和使用一个大的 numpy 数组,该数组太大而无法在内存中创建。 Numpy 支持内存映射,但据我所知,我的选择是:

  1. 使用 numpy.memmap 创建一个 memmap 文件。这会直接在磁盘上创建文件而不分配内存,但不存储元数据,所以当我稍后重新映射文​​件时,我需要知道它的 dtype、形状等。在下面,请注意不指定形状结果在被解释为平面数组的 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 保存它,之后可以在 memmapped 模式下加载它。这会将元数据与数组数据一起记录在磁盘上,但需要为整个数组至少分配一次内存。

【问题讨论】:

  • 为什么不把元数据也写入文件呢?

标签: python numpy


【解决方案1】:

当我看到 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
"""

【讨论】:

  • 我刚刚回到这个尝试一下。它有效 - 非常感谢。提醒一句:如果您使用错误的模式字符串,它可能会被静默接受并创建一个文件,但不会正确写入标题。写入新文件的唯一模式字符串是 'w+'。
  • 这似乎令人担忧。也许提交错误报告?
  • 我只是用这个方法写了一个38G的文件,并成功读取(至少几行)。据我了解,这不应该工作,因为此文件有 2GB 的限制。如果这个限制仍然成立,或者如何观察处理大文件时可能发生的任何问题,有什么想法吗?
  • @hamish 可能打开它以进行写入的唯一正确方法是 'w+' 因为在附加数据之后需要更新标头:数组大小(写入标头中的 shape 字段)创建文件时不知道。
  • 形状是 int 的元组也很重要,其他任何通常与数组一起使用的东西都会在稍后尝试加载它时导致错误。
【解决方案2】:

正如您自己发现的那样,NumPy 主要用于处理内存中的数据。有不同的库用于处理磁盘上的数据,今天最常用的可能是 HDF5。我建议查看h5py,它是 HDF5 库的优秀 Python 包装器。它旨在与 NumPy 一起使用,如果您已经了解 NumPy,它的界面很容易学习。要了解它如何解决您的问题,请阅读documentation of Datasets

为了完整起见,我应该提到PyTables,这似乎是在 Python 中处理大型数据集的“标准”方式。我没有使用它,因为 h5py 对我更有吸引力。两个库都有针对另一个库定义其范围的常见问题解答条目。

【讨论】:

  • 啊哈。非常感谢。我以前在浏览时遇到过这些,但一直受到精神障碍的困扰......
  • 确实,h5py的接口如果你已经了解Numpy的话,真的很容易上手。刚学会使用!谢谢!
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 2023-03-04
  • 2021-05-12
相关资源
最近更新 更多