Numpy 数组大于 RAM:写入磁盘还是核外解决方案?

EB2*_*127 6 python memory arrays numpy bigdata

我有以下工作流程,将数据附加到空的 pandas Series 对象。(这个空数组也可以是 NumPy 数组,甚至是基本列表。)

in_memory_array = pd.Series([])

for df in list_of_pandas_dataframes:
    new = df.apply(lambda row: compute_something(row), axis=1)  ## new is a pandas.Series
    in_memory_array = in_memory_array.append(new)
Run Code Online (Sandbox Code Playgroud)

我的问题是生成的数组in_memory_array对于 RAM 来说太大了。我不需要将所有对象保留在内存中进行此计算。

我认为一旦数组对于 RAM 来说太大,我的选择就是以某种方式将对象腌制到磁盘,例如

# N = some size in bytes too large for RAM
if sys.getsizeof(in_memory_array) > N: 
    with open('mypickle.pickle', 'wb') as f:
        pickle.dump(in_memory_array, f)
Run Code Online (Sandbox Code Playgroud)

否则,有没有核外解决方案?最好的情况是创建一些上限,使得对象在 RAM 中的增长不能超过 X GB。

小智 1

您可以将所有数据帧预处理为 numpy 数组,并将它们保存到一个或多个 npz 文件中(我对 npz 文件的经验有限,但我还没有找到一种附加到它们的方法。所以如果您的所有数据不适合RAM(如果空间有限,则必须创建多个 npz 文件)或压缩的 npz 文件,然后使用内存映射根据需要访问它们。当您将 npz 作为内存映射加载时,它会创建一个具有 numpy 数组名称的对象,而不会将数组加载到 RAM 中,直到您访问它们为止。举个例子:

def makeNPZ():
    z = np.zeros(100000)
    o = np.ones(100000)
    e = np.eye(100)

    dct = {'zero':z, 'one':o, 'eye':e}
    np.savez_compressed('TempZip.npz', **dct)

def useNPZ():
    return np.load('TempZip.npz', mmap_mode='r+')

makeNPZ()

memoryMap = useNPZ()

memoryMap.files
Out[6]: ['zero', 'one', 'eye']


memoryMap['one']
Out[11]: array([ 1.,  1.,  1., ...,  1.,  1.,  1.])
Run Code Online (Sandbox Code Playgroud)