NumPy将单个NPY文件加载到MemMap文件中会导致较高的内存使用率和较慢的批处理速度

时间:2018-09-16 20:50:42

标签: python numpy memory-management garbage-collection numpy-memmap

我正在处理大型数据集(起始为75GB->最终结果为两个100GB文件),并将数据分块为大约5000个单独的Numpy .npy文件。我试图遍历每个文件,进行一些处理和填充,然后存储到两个容器之一中。还有其他一些元数据数组,但是可以单独运行它们。但是,它们应该/需要能够与大数据处理保持一致。

我在脚本开头创建了两个内存映射文件

f1 = np.memmap('f1.dat', dtype='float32', mode='w+', shape=(2600, 5000, 2000))
f2 = np.memmap('f2.dat', dtype='float32', mode='w+', shape=(2500, 5000, 2000))
# f1 and f2 store different sets, depending on a flag

我在processData()中启用了数据处理功能,以返回元数据和大型数据数组。然后,将其添加或设置给定数组。这些都是在枚举的for循环中完成的。

for i, object in enumerate(object_list)
    meta1, meta2, data = processData(i, object)
    list_meta1.append(meta1)
    array_meta2[i] = meta2
    if flag_1:
        f1[j] = data; j+=1
    elif flag_2:
        f2[k] = data; k+=1

我已经尝试过将数据处理作为一种功能(我使用生成器进行了阅读,但可能会有点错了,哈哈),并使用了for循环。

我遇到的问题是,当我使用bash shell中的top监视python进程时,python进程正常加载。它将VIRT内存下的两个大数据文件“加载”到0.199t,并且在开始加载数据文件之前,在RES / SHR下大约需要一两个GB的空间。

但是,一旦开始如下所述实际开始处理数据:

data = np.load(object + ".npy")

meta1 = fetchMeta(1, object)
meta2 = fetchMeta(2, object)

if len(data) != whatItShouldBe[i]:
    sys.exit("You goof'd somewhere")
else:
    if len(data) < padding_limit:
        data = np.concatenate([np.array(data), np.zeros((padding_limit - len(data), 2000))], axis=0)

return meta1, meta2, data

RES内存量快速增长,在文件400左右时达到10GB左右,并且在某个时候将达到系统64GB的48GB。在整个处理过程中,直到达到48GB为止,Python处理过程中都有很多要点D(我知道这是不可中断的睡眠)。我以为这是让memmap将自身写入磁盘。

但是,手动刷新阵列不会释放任何内存或根本无法加快运行速度(如果有的话,它会在刷新刷新间隔约1分钟的时间内减慢速度)。

从本质上讲,我知道整个批处理过程很可能会及时完成,因为它会跳过前一百或两百个文件,将它们保存起来并继续进行运输。但是,存在一个“潜在”内存问题,似乎使事情陷入了困境。在我看来,没有理由让内存使用率在高使用率时保持保持状态(显然,两次写入磁盘之间的时间间隔会很高),但是在我看来,单个数据块由于某种原因(在将它们复制到正确的内存映射之后)被保留在内存中。

结尾说明:使用标准数组时,此代码的常规结构可以正常工作,但这是在非常小的数据集上进行的。为了清楚起见,我对代码进行了更多的匿名处理,但是可以在此处找到完整的实现:https://pastebin.com/nNZDxL0k

0 个答案:

没有答案