2011-12-15 12 views
7

Obtuve un objeto escabechado (una lista con algunas matrices numpy en él) que se creó en Windows y aparentemente se guardó en un archivo cargado como texto, no en modo binario (es decir. con open(filename, 'w') en lugar de open(filename, 'wb')). El resultado es que ahora no puedo descifrarlo (ni siquiera en Windows) porque está infectado con los caracteres \r (y posiblemente más)? La queja principal esPython pickle: corregir los caracteres antes de cargar

ImportError: No module named multiarray 

supuestamente porque está buscando numpy.core.multiarray\r, que por supuesto no existe. La simple eliminación de las \r caracteres no hacer el truco (intentado tanto sed -e 's/\r//g' y, en python s = file.read().replace('\r', ''), pero ambos romper el archivo y producir un cPickle.UnpicklingError más adelante)

El problema es que realmente necesito para obtener los datos de la objetos. Alguna idea de como arreglar los archivos?

Editar : A petición, los primeros cientos de bytes de mi archivo, Octal:

\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\[email protected]\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"\[email protected]\x0emovement_speedq\x12h\x06h\x08U\x08\\p\xf5[2\xc2\xef?\x86Rq\x13U\x0ctrial_lengthq\[email protected]\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\[email protected]\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\[email protected]\x86Rq"h\x0eh\x0fh\x10K\x00\x85U\x01b\x87Rq#(K\x01K\x02\x85h\x08\x89U\x10\xcd\xd9\x92\x9a\x94=\[email protected]]C\xaf\xef\xeb\xef\[email protected]\x12h\x06h\x08U\x08-\x9c&\x185\xfd\xef?\x86Rq$h\[email protected]\r\xb8W\xb2`V\xach\x15h\x16h\x17K\x02h\x18h\x06h\x08U\x08\x8e\x87\xd1\xc2 

También puede descargar el whole file (22k).

Respuesta

11

Suponiendo que el archivo fue creado con el protocolo predeterminado = método compatible con ASCII 0, debe ser capaz de cargar en cualquier lugar mediante el uso de open('pickled_file', 'rU') es decir, nuevas líneas universales.

Si esto no funciona, muéstrenos los primeros cien bytes: print repr(open('pickled_file', 'rb').read(200)) y pegue los resultados en una edición de su pregunta.

actualización después el contenido del archivo se publicaron:

El archivo comienza con '\x80\x02'; fue objeto de dumping con el protocolo 2, el último/mejor. Los protocolos 1 y 2 son binarios protocolos. Su archivo fue escrito en el modo de texto en Windows. Esto ha resultado en que cada '\n' se convierta a '\r\n' por el tiempo de ejecución de C. Los archivos deben ser abiertos en modo binario como esto:

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) 

Docs son here. Este código funcionará de manera portátil tanto en sistemas Windows como en sistemas que no sean de Windows.

Usted puede recuperar la imagen original de salmuera al leer el archivo en modo binario y luego revertir el daño mediante la sustitución de todas las apariciones de '\r\n' por '\n'. Nota: Este procedimiento de recuperación es necesario ya sea que intente leerlo en Windows o no.

+0

+1 para obtener información sobre la versión del protocolo de decapado. @Nkosinathi, debes marcar esto como la respuesta. –

0

¿No puede usted, en Windows, simplemente abrir el archivo en modo texto, de la misma manera que se escribió, leerlo y luego escribirlo en otro archivo abierto correctamente en modo binario?

0

Ha intentado deserialiación en modo texto? Es decir,

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

(En Windows, por supuesto.)

+0

No, al parecer, a Windows no le gustan sus propias terminaciones ...? –

5

Las líneas nuevas en Windows no son solo '\r', sino CRLF o '\r\n'.

Prueba file.read().replace('\r\n', '\n') para probar. Anteriormente borraba los retornos de carro que pueden no haber sido realmente parte de las nuevas líneas.

+0

+1: ¡lo tienes! Esto funciona en Mac OS X. De hecho, hay caracteres '\ r' aislados en el archivo de pickle. – EOL

+0

¡Brillante, eso lo resolvió! Gracias a un millón, ahorraste 4 horas de trabajo muy, muy caro (y no, definitivamente no por mi salario ... ;-) –

Cuestiones relacionadas