Numpy массив больше, чем RAM: запись на диск или решение вне ядра? - PullRequest
2 голосов
/ 26 марта 2020

У меня есть следующий рабочий процесс, посредством которого я добавляю данные в пустой объект pandas Series. (Этот пустой массив также может быть массивом NumPy или даже списком c.)

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)

Моя проблема в том, что результирующий массив in_memory_array становится слишком большим для оперативной памяти. Мне не нужно хранить все объекты в памяти для этого вычисления.

Я думаю, что мои варианты так или иначе выбирают объекты на диск, когда массив становится слишком большим для оперативной памяти, например,

# 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)

Иначе, есть ли решение вне ядра? В лучшем случае было бы создать такой предел, чтобы объект не мог быть больше, чем X ГБ в ОЗУ.

1 Ответ

0 голосов
/ 27 марта 2020

Вы можете предварительно обработать все ваши фреймы данных как numpy массивы и сохранить их в один или несколько файлов npz (у меня ограниченный опыт работы с файлами npz, но я не нашел способа добавить к ним. Так что если все ваши данные не помещаются в ОЗУ, вам придется создавать несколько файлов npz) или сжатые файлы npz, если пространство представляет собой проблему, а затем обращаться к ним по мере необходимости, используя отображение памяти. Когда вы загружаете npz в качестве карты памяти, он создает объект с именами массивов numpy без загрузки массивов в оперативную память до тех пор, пока вы не получите к ним доступ. Как пример:

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.])
...