Python сериализация объекта: проблема с pickle vs hickle - PullRequest
0 голосов
/ 07 марта 2020

Уже пару дней я застрял в своем проекте машинного обучения. У меня есть сценарий python, который должен преобразовывать данные для обучения модели вторым сценарием. В первом скрипте приведен список массивов, которые я хотел бы выгрузить на диск, во втором распаковываем его.

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

Traceback (most recent call last):
  File "Prepare_Input.py", line 354, in <module>
    pickle.dump(Total_Velocity_Change, file)
MemoryError

И иногда этот скрипт принудительно прекращает работу с сообщением Killed.

Я также пытался использовать hickle, однако скрипт продолжает работать в течение длительного времени hickle выдает огромный файл размером почти 10 ГБ (du -sh myfile.hkl), оставленный на ночь. Я уверен, что размер массива не может превышать 1,5 ГБ. Я также могу вывести массив на консоль (print). Используя hickle, мне пришлось убить процесс, чтобы остановить выполнение скрипта.

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

У кого-нибудь есть идеи, как можно безопасно выгрузить файл на диск для последующей загрузки? ?

Используя укроп я получаю следующие ошибки:

Traceback (most recent call last):
  File "Prepare_Input.py", line 356, in <module>
    dill.dump(Total_Velocity_Change, fp)
  File "/home/akil/Desktop/tmd/venv/lib/python3.7/site-packages/dill/_dill.py", line 259, in dump
    Pickler(file, protocol, **_kwds).dump(obj)
  File "/home/akil/Desktop/tmd/venv/lib/python3.7/site-packages/dill/_dill.py", line 445, in dump
    StockPickler.dump(self, obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 437, in dump
    self.save(obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 819, in save_list
    self._batch_appends(obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 843, in _batch_appends
    save(x)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 819, in save_list
    self._batch_appends(obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 843, in _batch_appends
    save(x)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 819, in save_list
    self._batch_appends(obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 843, in _batch_appends
    save(x)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 549, in save
    self.save_reduce(obj=obj, *rv)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 638, in save_reduce
    save(args)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 774, in save_tuple
    save(element)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 504, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 735, in save_bytes
    self.memoize(obj)
  File "/home/akil/anaconda3/lib/python3.7/pickle.py", line 461, in memoize
    self.memo[id(obj)] = idx, obj
MemoryError

1 Ответ

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

Если вы хотите сбросить огромный список массивов, вы можете посмотреть на dask или klepto. dask может разбить список на списки подмассивов, в то время как klepto может разбить список на части подмассивов (с ключом, указывающим порядок подмассивов).

>>> import klepto as kl
>>> import numpy as np
>>> big = np.random.randn(10,100)  # could be a huge array
>>> ar = kl.archives.dir_archive('foo', dict(enumerate(big)), cached=False)
>>> list(ar.keys())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 

Затем одна запись на файл сериализуется на диск (в файле output.pkl)

$ ls foo/K_0/
input.pkl   output.pkl
...