【发布时间】:2013-09-04 13:16:23
【问题描述】:
目前我正在研究一个非常庞大的数据集,几乎不适合我的记忆,所以我使用np.memmap。但在某些时候,我必须将我的数据集拆分为训练和测试。
当我想使用一些索引数组对np.memmap 进行切片时,我发现了这种情况:
(您可以在下面找到代码和内存分配)
Line # Mem usage Increment Line Contents
================================================
7 29.340 MB 0.000 MB def my_func2():
8 29.340 MB 0.000 MB ARR_SIZE = (1221508/4,430)
9 29.379 MB 0.039 MB big_mmap = np.memmap('big_mem_test.mmap',shape=ARR_SIZE, dtype=np.float64, mode='r')
10 38.836 MB 9.457 MB idx = range(ARR_SIZE[0])
11 2042.605 MB 2003.770 MB sub = big_mmap[idx,:]
12 3046.766 MB 1004.160 MB sub2 = big_mmap[idx,:]
13 3046.766 MB 0.000 MB return type(sub)
但如果我喜欢连续切片,我会使用以下代码:
Line # Mem usage Increment Line Contents
================================================
15 29.336 MB 0.000 MB def my_func3():
16 29.336 MB 0.000 MB ARR_SIZE = (1221508/4,430)
17 29.375 MB 0.039 MB big_mmap = np.memmap('big_mem_test.mmap',shape=ARR_SIZE, dtype=np.float64, mode='r')
18 29.457 MB 0.082 MB sub = big_mmap[0:1221508/4,:]
19 29.457 MB 0.000 MB sub2 = big_mmap[0:1221508/4,:]
请注意,在第 18,19 行的第二个示例中,没有内存分配,整个操作要快得多。
在第 11 行的第一个示例中,有一个位置,因此在切片期间会读取整个 big_mmap 矩阵。但更令人惊讶的是第 12 行还有另一个位置。做更多这样的操作很容易耗尽内存。
当我拆分数据集时,索引相当随机且不连续,因此我无法使用big_mmap[start:end,:] 表示法。
我的问题是:
有没有其他方法可以让我在不将整个数据读取到内存的情况下对 memmap 进行切片?
为什么在使用索引切片时将整个矩阵读入内存(示例一)?
为什么要再次读取和分配数据(第一个示例第 12 行)?
【问题讨论】:
-
我想建议通过 h5py 库而不是 memmap 使用 hdf5 文件。它们更灵活(也更强大)并且非常易于使用。
-
是的,我正在考虑它,实际上我正在考虑在底部使用 hdf5 的PyTables。但我仍然对这种 memmap 行为感兴趣。
-
我知道这是最简单的出路,但您是否考虑购买更多内存? (这避免了问题而不是解决问题,但是稍后当您的数据增长更多时,您将再次遇到同样的问题)
-
@usethedeathstar 实际上是相反的。如果我购买更多内存,我将再次面临更大数据集的问题。但是如果我用一种磁盘分页来解决它。我将能够处理数据,购买 ram 只会加快整个过程。