我有几个大型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的解决方案。
答案 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'].value
或f['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
的结果总是一个数组,其中所有数据都在一个连续的内存块中。永远不会存在于文件中的数据块。
您需要告诉我们更多有关这个大型连锁数组集的意图。作为大纲,我认为您可以构建包含所有数据集切片的数组。您还可以执行我在上一个答案中演示的其他操作 - 但访问时间成本。