2012-05-10 19 views
8

Me gustaría guardar el contenido de una matriz flotante numpy en un archivo binario sin formato como enteros de 16 bits con signo. Traté de lograr esto usando ndarray.tofile pero no puedo encontrar la cadena de formato correcta. Parece que el archivo se guarda en formato doble, independientemente de cómo elija la cadena de formato. ¿Cómo hago esto? Gracias.Escribir un archivo binario en bruto con datos de la matriz NumPy

Respuesta

19

Creo que la forma más sencilla de hacerlo es convertir primero la matriz a Int16,

array.astype('int16').tofile(filename) 
+1

El [Documentación numpy] (http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.ndarray.tofile.html) declara que "se perdió información sobre endianness y precisión". ¿Esto está garantizado para trabajar en todas las plataformas? – Gilly

+3

'tofile' solo escribe los datos binarios en bruto de la matriz, no los metadatos de la matriz. Un caso de uso típico es abrir un archivo, escribir un encabezado apropiado para el tipo de archivo y usar 'tofile' para completar los datos brutos. Es responsabilidad del software que lee el archivo inferir los metadatos (endianness, precision, shape) del encabezado y mutar los datos sin procesar en un formato apropiado para esa plataforma. Sin metadatos, no hay forma de interpretar correctamente el contenido sin formato de la matriz. Si todo lo que necesita es leer y escribir matrices, consulte "python hd5" o "numpy.save". –

+0

¡Gracias! Este 'astype' adicional fue necesario incluso cuando creé la matriz especificando' np.array ([], dtype = np.int8) '. –

8

Tome una mirada en el módulo de estructura, probar este ejemplo:

import struct 
import numpy 

f=open("myfile","wb") 
mydata=numpy.random.random(10) 
print(mydata) 
myfmt='f'*len(mydata) 
# You can use 'd' for double and <or> to force endinness 
bin=struct.pack(myfmt,*mydata) 
print(bin) 
f.write(bin) 
f.close() 
+10

Según la experiencia, le recomiendo encarecidamente ** en contra de ** el uso de 'struct.pack'. Su API requiere que exija la matriz (es decir, use el operador '*') en variables que afectan el rendimiento ** drásticamente ** para tamaños de matriz grandes. Cada elemento de la matriz necesitará un nuevo puntero de 64 bits sobre la marcha (en una máquina de 64 bits) que se creará en la pila para apuntar a ese elemento. Solo adhiérase a 'tostring' /' tobytes'/'tofile' para evitar esta sobrecarga. Por ejemplo, en nuestro caso, estábamos lidiando con matrices de 100 Mb lo que lleva a 6.4Gb de RAM por lo que 'struct.pack' puede hacer su trabajo. –

0

Usted puede scipy.io.savemat uso que permite guardar un diccionario de nombres y matrices en el archivo de estilo Matlab:

import scipy.io as sio 
sio.savemat(filename, pydict) 
Aquí

pydict puede ser = { 'tipo1': np.array1, 'tipo2': np.array2, ...}

Para cargar el dict sólo tiene:

pydict = sio.loadmat(filename) 
Cuestiones relacionadas