有没有办法让一个 numpy 样式的视图查看存储在 hdf5 文件中的数组切片?

Posted

技术标签:

【中文标题】有没有办法让一个 numpy 样式的视图查看存储在 hdf5 文件中的数组切片?【英文标题】:Is there a way to get a numpy-style view to a slice of an array stored in a hdf5 file? 【发布时间】:2015-03-04 09:29:56 【问题描述】:

我必须处理大型 3D 立方体数据。我想将它们存储在 HDF5 文件中(使用 h5py 或 pytables)。我经常只想对这些立方体的一部分进行分析。此部分太大而无法保存在内存中。我想对我感兴趣的部分有一个 numpy 样式的视图,而无需将数据复制到内存(类似于您可以使用 numpy memmap 执行的操作)。这可能吗?据我所知,使用 h5py 执行切片,你会在内存中得到一个 numpy 数组。

有人问我为什么要这样做,因为无论如何数据都必须在某个时候进入内存。出于必要,我的代码已经对来自这些多维数据集的数据零碎地运行,一次将一小部分数据拉入内存。如果这些函数只是遍历传递给它们的全部数据集,则它们是最简单的。如果我可以查看磁盘上的数据,我只需将这个视图原封不动地传递给这些函数。如果我无法查看,我需要编写所有函数来仅迭代感兴趣的切片。这将增加代码的复杂性,并使其在分析过程中更容易出现人为错误。

有什么方法可以查看磁盘上的数据,而不需要复制到内存?

【问题讨论】:

你听说过pandas。它在reading/writing an HDF5 store 中可能非常有用? 这是我之前的问题的后续:***.com/q/27710245/1361752 是的,我对 pandas DataFrames 非常熟悉(尽管它们的 3D 功能并不多)。但是,这主要在内存中起作用,对吗?我知道您可以使用 pytables 将表复制到 hdf5 文件。有没有办法将它用于我需要的功能?此外,我认为熊猫通常为表格数据提供高级数据类型。对于简单的数组来说是不是有点矫枉过正?也就是说,如果它满足我的需求,我会很乐意使用它。 如果您需要整个子集来进行处理,而该子集不适合内存,那么我看不出如何在不更新处理以处理子集。除此之外,h5py 还支持类似 numpy 的切片,它应该通过 hyperslab 选择起作用,但我对您的数据知之甚少,无法说明这是否足够。 对我来说,这听起来像 dask 数组将是您正在搜索的内容(尽管我应该说我从未将它用于严肃的应用程序)。它的设计完全符合您的描述:数据太大而无法放入内存,并与pandasnumpy 等知名工具集成。请参阅主网站:dask.pydata.org/en/latest/docs.html 以及如何创建 dask 数组,同样来自 hfd5:dask.pydata.org/en/latest/array-creation.html。至少在他们的文档中,他们写道“将空间限制从“适合内存”更改为“适合磁盘”。 【参考方案1】:

一种可能性是创建一个generator,它会一一生成切片的元素。一旦你有了这样的生成器,你就可以将它传递给你现有的代码,并像往常一样遍历生成器。例如,您可以在生成器上使用 for 循环,就像在切片上使用它一样。生成器不会一次存储它们的所有值,它们会根据需要“生成”它们。

您可以只创建您想要的多维数据集位置的切片,而不是数据本身,或者如果您有太多位置需要存储在内存中,您也可以通过编程方式生成切片的下一个位置。生成器可以使用这些位置来一一生成它们包含的数据。

假设您的切片是长方体的(可能是更高维度的)等价物,您可以使用嵌套的for-range() 循环生成坐标,或者通过将itertools 模块中的product() 应用于范围对象。

【讨论】:

【参考方案2】:

不将数据集的该部分复制到内存是不可避免的。 这样做的原因仅仅是因为您请求的是整个部分,而不仅仅是其中的一小部分。 因此,必须完全复制。

因此,由于h5py 已经允许您以与 NumPy 数组相同的方式使用 HDF5 数据集,因此您必须更改代码以仅请求数据集中当前需要的值。

【讨论】:

以上是关于有没有办法让一个 numpy 样式的视图查看存储在 hdf5 文件中的数组切片?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法使用布局页面向 MVC 视图的主体添加样式

存储在numpy void中的数组不返回形状/长度

有没有办法在 numpy 中执行这个子采样算法?

给定一个 numpy 数组视图中项目的索引,在基本数组中找到它的索引

广播到 Numpy 数组的视图中

有没有办法让单个视图不旋转?