我如何懒洋洋地连接" numpy ndarray" -like对象进行顺序阅读?

时间:2017-01-10 15:43:45

标签: python numpy multidimensional-array h5py

我有几个大型hdf5文件的列表,每个文件都有一个4D数据集。我想在第一个轴上获得它们的串联,就像在一个类似于数组的对象一样,它将被用作所有数据集的连接。我的最终目的是多次沿同一轴顺序读取数据块(例如[0:100,:,:,:][100:200,:,:,:],...)。

h5py中的数据集共享numpy数组API的重要部分,这使我可以调用numpy.concatenate来完成工作:

files = [h5.File(name, 'r') for name in filenames]
X = np.concatenate([f['data'] for f in files], axis=0)

另一方面,内存布局不一样,内存不能在它们之间共享(related question)。唉,concatenate会急切地将每个类数组对象的整个内容复制到一个新数组中,在我的用例中我无法接受。数组连接函数的source code确认了这一点。

如何获得多个类似数组的对象的连接视图,没有急切地将它们读入内存?就这个视图而言,对这个视图进行切片和索引就像我有一个连接数组一样。

我可以想象编写自定义包装器会起作用,但我想知道这样的实现是否已经作为库存在,或者是否可以使用其他解决方案并且同样可行。到目前为止,我的搜索没有产生任何类似的东西。我也愿意接受特定于h5py的解决方案。

1 个答案:

答案 0 :(得分:0)

flist = [f['data'] for f in files]dataset个对象的列表。实际数据位于h5文件上,只要这些文件保持打开状态,就可以访问这些文件。

当你这样做时

arr = np.concatenate(flist, axis=0)

我想concatenate首先做

tmep = [np.asarray(a) for a in flist]

即构造一个numpy数组列表。我假设np.asarray(f['data'])f['data'].valuef['data'][:]相同(正如我在2年前在链接的SO问题中所讨论的那样)。我应该做一些与

比较的时间测试
arr = np.concatenate([a.value for a in flist], axis=0)

flist是这些数据集的一种惰性编译,因为数据仍然驻留在文件中,只有在您执行更多操作时才能访问。

[a.value[:,:,:10] for a in flist]

将每个数据集的一部分加载到内存中;我希望该列表上的连接将等同于arr[:,:,:10]

生成器或生成器理解是惰性求值的一种形式,但我认为它们必须在concatenate中使用之前转换为列表。在任何情况下,concatenate的结果总是一个数组,其中所有数据都在一个连续的内存块中。永远不会存在于文件中的数据块。

您需要告诉我们更多有关这个大型连锁数组集的意图。作为大纲,我认为您可以构建包含所有数据集切片的数组。您还可以执行我在上一个答案中演示的其他操作 - 但访问时间成本。