Tengo prácticamente ningún conocimiento de Matlab, y la necesidad de traducir algunas rutinas de análisis en Python. Son para archivos de gran tamaño, que se divide en ‘bloques’, y estoy teniendo dificultad desde el apagado con la suma de comprobación en la parte superior del archivo.

Exactamente lo que está pasando aquí en Matlab?

status = fseek(fid, 0, 'cof');
fposition = ftell(fid);
disp(' ');
disp(['** Block ',num2str(iBlock),' File Position = ',int2str(fposition)]);

% ----------------- Block Start ------------------ %
[A, count] = fread(fid, 3, 'uint32');
if(count == 3)
    magic_l = A(1);
    magic_h = A(2);
    block_length = A(3);
else
    if(fposition == file_length)
        disp(['** End of file OK']);
    else
        disp(['** Cannot read block start magic !  Note File Length = ',num2str(file_length)]);
    end
    ok = 0;
    break;
end

fid es el archivo que actualmente se están estudiando
iBlock es un contador que ‘bloque’ que está dentro del archivo

magic_l y magic_h tienen que ver con las sumas de comprobación después, aquí está el código para que (sigue directamente desde el código anterior):

disp(sprintf('  Magic_L = %08X, Magic_H = %08X, Length = %i', magic_l, magic_h, block_length));
correct_magic_l = hex2dec('4D445254');
correct_magic_h = hex2dec('43494741');

if(magic_l ~= correct_magic_l | magic_h ~= correct_magic_h)
    disp(['** Bad block start magic !']);
    ok = 0;
    return;
end

remaining_length = block_length - 3*4 - 3*4;   % We read Block Header, and we expect a footer
disp(sprintf('  Remaining Block bytes = %i', remaining_length));
  • Lo que está pasando con la %08X y la hex2dec cosas?
  • También, ¿por qué especificar 3*4 en lugar de 12?

Aunque realmente, quiero saber cómo replicar [A, count] = fread(fid, 3, 'uint32'); en Python, como io.readline() está tirando de los 3 primeros caracteres del archivo. Le pido disculpas si me estoy perdiendo el punto en algún lugar de aquí. Es sólo que el uso de io.readline(3) en el archivo parece devolver algo que no debería, y no entiendo cómo la block_length puede caber en un único byte al que podría ser muy larga.

Gracias por leer este paseo. Espero que usted pueda entender lo que quiero saber! (Cualquier reflexión a todos los que se aprecia.)

Usted puede ser que desee pensar acerca de la división de la pregunta y mover la segunda parte en otra pregunta, el título es un poco engañoso.

OriginalEl autor Duncan Tait | 2010-01-27

4 Comentarios

  1. 7

    De la documentación de fread, es una función para leer los datos binarios. El segundo argumento especifica el tamaño de la salida de vectores, la tercera el tamaño y tipo de los elementos de leer.

    Con el fin de recrear esto en Python, puede utilizar el array módulo:

    f = open(...)
    import array
    a = array.array("L")  # L is the typecode for uint32
    a.fromfile(f, 3)

    Esto va a leer tres uint32 valores del archivo f, que están disponibles en a después. A partir de la documentación de fromfile:

    Leer n elementos (como la máquina de valores) en el archivo de objeto f y añadirlas a la final de la matriz. Si hay menos de n elementos disponibles, EOFError es elevado, pero los elementos que estaban disponibles todavía se inserta en la matriz. f debe ser un verdadero incorporado en el archivo de objeto; algo más con un método read() no.

    Matrices de implementar la secuencia de protocolo y, por tanto, de apoyo a las mismas operaciones como las listas, pero también se puede utilizar el .tolist() método para crear una lista normal de la matriz.

    Gracias, esto realmente ayudó a – todo trabaja ahora!

    OriginalEl autor Torsten Marek

  2. 9

    Código de Python para la Lectura de un 1-Dimensiones de la Matriz de

    Cuando la sustitución de Matlab con Python, yo quería leer los datos binarios en un numpy.matriz, así que he usado numpy.fromfile para leer los datos en un 1-matriz bidimensional:

    import numpy as np
    
    with open(inputfilename, 'rb') as fid:
        data_array = np.fromfile(fid, np.int16)

    Algunas de las ventajas de la utilización de numpy.fromfile frente a otros Python soluciones incluyen:

    • No tener que determinar manualmente el número de elementos a ser leído. Se pueden especificar utilizando la count= argumento, pero se reduce a -1 que indica la lectura de la totalidad del expediente.
    • Ser capaz de especificar un archivo abierto objeto (como hice anteriormente con fid) o puede especificar un nombre de archivo. Yo prefiero usar un archivo abierto objeto, pero si se desea utilizar un nombre de archivo, que podrían reemplazar a las dos líneas de arriba con:

      data_array = numpy.fromfile(inputfilename, numpy.int16)

    Código de Matlab para un 2-Dimensiones de la Matriz de

    De Matlab fread tiene la capacidad de leer los datos en una matriz de la forma [m, n] en lugar de limitarse a la lectura en un vector columna. Por ejemplo, para leer los datos en una matriz de 2 filas de uso:

    fid = fopen(inputfilename, 'r');
    data_array = fread(fid, [2, inf], 'int16');
    fclose(fid);

    Equivalente Código de Python para un 2-Dimensiones de la Matriz de

    Usted puede manejar este escenario en Python usando Numpy del shape y transpose.

    import numpy as np
    
    with open(inputfilename, 'rb') as fid:
        data_array = np.fromfile(fid, np.int16).reshape((-1, 2)).T
    • La -1 dice numpy.remodelar para deducir la longitud de la matriz para que la dimensión basada en la otra dimensión—el equivalente de Matlab inf infinito representación.
    • La .T transpone la matriz por lo que es un 2-matriz bidimensional con la primera dimensión, la dimensión de los ejes con una longitud de 2.
    Gran respuesta, bien explicado, con buenos ejemplos claros.

    OriginalEl autor Matthew Rankin

  3. 2

    Aunque realmente, quiero saber cómo replicar [A, count] = fread(fid, 3, 'uint32');

    En Matlab, uno de fread()‘s de firmas es fread(fileID, sizeA, precision). Así, se lee en la primera sizeA elementos (no bytes) de un archivo, cada uno de un tamaño suficiente para precision. En este caso, ya que usted está leyendo en uint32, cada elemento es de tamaño 32 bits o 4 bytes.

    Así que, en lugar, trate de io.readline(12) para obtener los 3 primeros 4 bytes de los elementos del archivo.

    OriginalEl autor John Feminella

  4. 0

    La primera parte está cubierto por Torsten la respuesta… vas a necesitar array o numarray a hacer nada con los datos de todos modos.

    Como para el %08X y la hex2dec cosas, %08X es sólo el formato de impresión para aquellos unit32 números (8 dígitos hexadecimales, exactamente el mismo que el de Python), y hex2dec(‘4D445254’) es matlab para 0x4D445254.

    Finalmente, ~= en matlab es un bit a bit compare; use == en Python.

    OriginalEl autor Andrew McGregor

Dejar respuesta

Please enter your comment!
Please enter your name here