Как разделить большие данные и вернуться позже - PullRequest
0 голосов
/ 13 декабря 2018

Мой код генерирует список числовых массивов размером (1, 1, n, n, m, m), где n может варьироваться от 50-100, а m - от 5-10 в зависимости от рассматриваемого случая.Длина самого списка может достигать 10000 и записывается / выгружается с использованием pickle в конце кода.Для случаев с более высоким значением этих чисел или когда размеры файлов превышают 5-6 ГБ, я получаю ошибку Out of Memory .Ниже приведен пример ситуации:

import numpy as np
list, list_length = [], 1000
n = 100
m = 3
for i in range(0, list_length):
   list.append(np.random.random((1, 1, n, n, m, m)))

file_path = 'C:/Users/Desktop/Temp/'
with open(file_path, 'wb') as file:
    pickle.dump(list, file)

Я ищу способ, который поможет мне

  • разбить данные, чтобы я мог избавиться от ошибки памятии
  • воссоединение данных в исходной форме при необходимости позже

Все, что я мог бы подумать, это:

for i in range(0, list_length):
   data = np.random.random((1, 1, n, n, m, m))
   file_path = 'C:/Users/Desktop/Temp/'+str(i)
   with open(file_path, 'wb') as file:
      pickle.dump(data, file)

и затем объединить, используя:

combined_list = []
for i in range(0, list_length):
    file_path = 'C:/Users/Desktop/Temp/single' + str(i)
    with open(file_path, 'rb') as file:
        data = pickle.load(file)
    combined_list.append(data)

При таком способе размер файла, безусловно, уменьшается из-за нескольких файлов, но это также увеличивает время обработки из-за нескольких операций ввода-вывода файлов.

Существует ли более элегантный и лучший способсделать это?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Использование savez, savez_compressed или даже таких вещей, как h5py, может быть полезно, как упомянуто @tel, но это требует дополнительных усилий, пытаясь "изобрести" механизм кэширования.Существует два более простых способа обработки объема памяти ndarray, если это применимо:

  • Самый простой способ , конечно, включает pagefile (или некоторые другиеname) в Windows или swap в Linux (не уверен насчет счетчика OS X).Это создает практически достаточно большой объем памяти, так что вам не нужно беспокоиться о памяти вообще.Это сохранит на диск / загрузит с диска соответственно

  • Если первый способ неприменим из-за отсутствия прав администратора и т. Д., numpy предоставляет другой способ: np.memmap.Эта функция отображает ndarray на диск, так что вы можете индексировать его так же, как он находится в памяти.Технически ввод-вывод выполняется непосредственно на жесткий диск, но ОС соответственно кэширует

Для второго способа вы можете создать сторону жесткого диска ndarray, используя:

np.memmap('yourFileName', 'float32', 'w+', 0, 2**32)

Это создает массив 16GB float32 в кратчайшие сроки (содержащий номера 4G).Вы можете сделать IO для этого.Многие функции имеют параметр out.Вы можете соответственно установить параметр out, чтобы вывод не «копировался» на диск из памяти

Если вы хотите сохранить список ndarray с использованием второго метода, либо создайте многоmemmap с, или объединить их в один массив

0 голосов
/ 13 декабря 2018

Не используйте pickle для хранения больших данных, это не эффективный способ сериализации чего-либо.Вместо этого используйте встроенные форматы / функции numy serialization с помощью функций numpy.savez_compressed и numpy.load.

Системная память не бесконечна, поэтому приВ какой-то момент вам все равно придется разделить ваши файлы (или использовать более тяжелое решение, такое как решение, предоставляемое пакетом h5py).Однако, если вы смогли разместить исходный список в памяти, тогда savez_compressed и load должны делать то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...