我有一个HDF5文件,包含2000000行,每行有8个float32列。原始内存的总大小应该大约为640MB。
我想在我的Python应用程序中加载这些数据,但是,在加载到numpy数组的过程中,我耗尽了内存(我有64GB RAM)
我使用这个代码:
import h5py
hf = h5py.File(dataFileName, 'r')
data = hf['data'][:]
对于较小的文件,它工作正常,但是,我的输入不是那么大,以及。那么有没有其他方法可以将整个数据集加载到内存中,因为它应该适合没有任何问题。另一方面,为什么它需要这么多内存?即使它会在内部将float32转换为float64,它也不会接近整个RAM的大小。
数据集信息来自HDFView 3.3.0
3条答案
按热度按时间ca1c2owp1#
出现问题的第一个迹象可能是文件虽然包含大约500 MiB的数据,但实际上大小大约为850 MiB;至少在我把它复制到我的系统上时是这样。这表明开销过大。
微小的块大小加上相当大的数据集大小显然会破坏HDF 5库,或者至少会让它分配大量的内存。作为测试,如果我没有足够快地杀死进程,这将消耗系统上的所有内存和交换:
这样做是可行的,但速度非常慢:
同样,您也不能用如此可笑的块大小一次读取所有内容。如果要我猜原因的话,库可能想在阅读它们之前弄清楚所有块的位置。这会将磁盘上相当紧凑的表示转换为内存中的大表示。
尝试以下方法作为解决方法:
请告诉创建这些文件的人仔细阅读块大小的含义并选择一个合适的;通常在64 kB到1 MiB的范围内。
gzszwxb42#
你说的没错。如果您仅将单个640 MB数据集加载到具有64 GB RAM的系统上的单个NumPy数组,则不应耗尽内存。如果你是,问题可能在其他地方。您是否同时加载了很多数组?你的程序是否有其他需要大量内存的对象?是否有其他运行的应用程序也消耗大量内存?
首先用一个简单的测试用例诊断行为。我写了一个程序来创建一个包含1个数据集的HDF 5文件,关闭文件,然后打开并将其读入1个数组。这运行在我的系统与24 GB内存,并应运行在您的系统。(代码在最后。)如果它对你有效,那就确认了你可以读这个大小的数组,问题出在你程序的其他地方。如果它不运行,那么在您的系统上使用HDF 5/h5 py会出现更大的问题。
注意:您还可以通过创建数据集对象来减少内存使用。这些“行为类似”NumPy数组,但内存占用要小得多。这也在代码中得到了证明。
验证码:
wtzytmuj3#
如果你不能让“某人”为你重新创建文件,你可以自己做。下面的代码使用@Homer512建议的相同方法来复制数据。它使用
chunks=(30_000,8)
创建一个新文件和数据集。这将提供给予更好的I/O性能。新文件中数据集的读取时间小于一秒。我的代码中的计时和打印语句不是必需的。我把它们包括进来是为了在跑步时得到一些反馈。请注意,36行的行读取因子适用于此数据集,并避免在最后一次循环中进行增量读取。你将不得不调整它以适应更一般的情况。
代码如下: