Python pickle: исправьте символы \ r перед загрузкой - PullRequest
8 голосов
/ 16 декабря 2011

Я получил засоленный объект (список с несколькими массивами в нем), который был создан в Windows и, очевидно, сохранен в файл, загруженный как текст, а не в двоичном режиме (т. Е. С open(filename, 'w') вместо open(filename, 'wb') ). Результатом является то, что теперь я не могу открыть его (даже в Windows), потому что он заражен \r символами (и, возможно, больше)? Основная жалоба

ImportError: No module named multiarray

предположительно, потому что он ищет numpy.core.multiarray\r, которого, конечно, не существует. Простое удаление символов \r не сработало (пробовал и sed -e 's/\r//g', и в python s = file.read().replace('\r', ''), но оба ломали файл и позже получали cPickle.UnpicklingError)

Проблема в том, что мне действительно нужно получить данные из объектов. Есть идеи как починить файлы?

Редактировать: По запросу первые несколько сотен байтов моего файла, Восьмеричное число:

\x80\x02]q\x01(}q\x02(U\r\ntotal_timeq\x03G?\x90\x15r\xc9(s\x00U\rreaction_timeq\x04NU\x0ejump_directionq\x05cnumpy.core.multiarray\r\nscalar\r\nq\x06cnumpy\r\ndtype\r\nq\x07U\x02f8K\x00K\x01\x87Rq\x08(K\x03U\x01<NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tbU\x08\x025\x9d\x13\xfc#\xc8?\x86Rq\tU\x14normalised_directionq\r\nh\x06h\x08U\x08\xf0\xf9,\x0eA\x18\xf8?\x86Rq\x0bU\rjump_distanceq\x0ch\x06h\x08U\x08\x13\x14\xea&\xb0\x9b\x1a@\x86Rq\rU\x04jumpq\x0ecnumpy.core.multiarray\r\n_reconstruct\r\nq\x0fcnumpy\r\nndarray\r\nq\x10K\x00\x85U\x01b\x87Rq\x11(K\x01K\x02\x85h\x08\x89U\x10\x87\x16\xdaEG\xf4\xf3?\x06`OC\xe7"\x1a@tbU\x0emovement_speedq\x12h\x06h\x08U\x08\\p\xf5[2\xc2\xef?\x86Rq\x13U\x0ctrial_lengthq\x14G@\t\x98\x87\xf8\x1a\xb4\xbaU\tconditionq\x15U\x0bhigh_mentalq\x16U\x07subjectq\x17K\x02U\x12movement_directionq\x18h\x06h\x08U\x08\xde\x06\xcf\x1c50\xfd?\x86Rq\x19U\x08positionq\x1ah\x0fh\x10K\x00\x85U\x01b\x87Rq\x1b(K\x01K\x02\x85h\x08\x89U\x10K\xb7\xb4\x07q=\x1e\xc0\xf2\xc2YI\xb7U&\xc0tbU\x04typeq\x1ch\x0eU\x08movementq\x1dh\x0fh\x10K\x00\x85U\x01b\x87Rq\x1e(K\x01K\x02\x85h\x08\x89U\x10\xad8\x9c9\x10\xb5\xee\xbf\xffa\xa2hWR\xcf?tbu}q\x1f(h\x03G@\t\xba\xbc\xb8\xad\xc8\x14h\x04G?\xd9\x99%]\xadV\x00h\x05h\x06h\x08U\x08\xe3X\xa9=\xc1\xb1\xeb?\x86Rq h\r\nh\x06h\x08U\x08\x88\xf7\xb9\xc1\t\xd6\xff?\x86Rq!h\x0ch\x06h\x08U\x08v\x7f\xeb\x11\xea5\r@\x86Rq"h\x0eh\x0fh\x10K\x00\x85U\x01b\x87Rq#(K\x01K\x02\x85h\x08\x89U\x10\xcd\xd9\x92\x9a\x94=\x06@]C\xaf\xef\xeb\xef\x02@tbh\x12h\x06h\x08U\x08-\x9c&\x185\xfd\xef?\x86Rq$h\x14G@\r\xb8W\xb2`V\xach\x15h\x16h\x17K\x02h\x18h\x06h\x08U\x08\x8e\x87\xd1\xc2

Вы также можете загрузить весь файл (22k).

Ответы [ 4 ]

14 голосов
/ 16 декабря 2011

Предполагая, что файл был создан с протоколом по умолчанию = 0 ASCII-совместимым методом, вы сможете загружать его где угодно, используя open('pickled_file', 'rU'), т. Е. Универсальные символы новой строки.

Если это не сработает, покажите нам первые несколько сотен байтов: print repr(open('pickled_file', 'rb').read(200)) и вставьте результаты в редактирование вашего вопроса.

Обновление после публикации содержимого файла:

Ваш файл начинается с '\x80\x02'; он был сброшен с протоколом 2, последний / лучший. Протоколы 1 и 2 являются двоичными протоколами. Ваш файл был написан в режиме text в Windows. Это привело к тому, что каждый '\n' был преобразован в '\r\n' во время выполнения C. Файлы должны быть открыты в двоичном режиме, например:

with open('result.pickle', 'wb') as f: # b for binary
    pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)

with open('result.pickle', 'rb') as f: # b for binary
    obj = pickle.load(f)

Документы здесь . Этот код будет работать переносимо как в Windows, так и в других системах.

Вы можете восстановить исходное изображение засолки, прочитав файл в двоичном режиме, а затем восстановив ущерб, заменив все вхождения '\r\n' на '\n'. Примечание. Эта процедура восстановления необходима независимо от того, пытаетесь ли вы прочитать ее в Windows или нет.

5 голосов
/ 16 декабря 2011

Новые строки в Windows - это не просто '\r', это CRLF или '\r\n'.

Дайте file.read().replace('\r\n', '\n') попробовать. Ранее вы удаляли возврат каретки, который, возможно, фактически не был частью новой строки.

0 голосов
/ 16 декабря 2011

Вы пробовали открепление в текстовом режиме?То есть

x = pickle.load(open(filename, 'r'))

(В Windows, конечно.)

0 голосов
/ 16 декабря 2011

Разве вы не можете - в Windows - просто открыть файл в текстовом режиме, так же, как он был записан, прочитать его, а затем записать его в другой файл, правильно открытый в двоичном режиме?

...