SciPy, entrada y salida en MATLAB


SciPy (pronunciado sai pie) es un paquete de aplicación matemática basado en la extensión Numpy Python. Con SciPy, una sesión interactiva de Python se convierte en el mismo entorno completo de procesamiento de datos y creación de prototipos para sistemas complejos como MATLAB, IDL, Octave, R-Lab y SciLab. En esta publicación, me gustaría hablar sobre las posibilidades del paquete scipy.io I / O, que permite trabajar con archivos de datos Octave y MATLAB.


Introduccion


Primero, importe el paquete scipy.io de la siguiente manera:


import scipy.io as sio 

Los principales procedimientos del paquete scipy.io que le permiten trabajar con archivos MATLAB:


 sio.loadmat sio.savemat sio.whosmat 

Para no violar el acuerdo de licencia de MATLAB, trabajaremos en el entorno GNU Octave, que tiene funciones de guardar y cargar compatibles con MATLAB. En el indicador de octava, ingrese:


 octave:1> a = 1:12 a = 1 2 3 4 5 6 7 8 9 10 11 12 octave:2> a = reshape(a, [1 3 4]) a = ans(:,:,1) = 1 2 3 ans(:,:,2) = 4 5 6 ans(:,:,3) = 7 8 9 ans(:,:,4) = 10 11 12 octave:3> save -6 octave_a.mat a % MATLAB 6 compatible octave:4> ls octave_a.mat octave_a.mat 

Código para importar archivos MATLAB en Python:


 mat_contents = sio.loadmat('octave_a.mat') mat_contents 

  {'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.2.2, 2019-02-02 20:26:43 UTC', '__version__': '1.0', '__globals__': [], 'a': array([[[ 1., 4., 7., 10.], [ 2., 5., 8., 11.], [ 3., 6., 9., 12.]]])} 

 oct_a = mat_contents['a'] oct_a 

  array([[[ 1., 4., 7., 10.], [ 2., 5., 8., 11.], [ 3., 6., 9., 12.]]]) 

 oct_a.shape 

 (1, 3, 4) 

Como puede ver, el archivo se leyó correctamente. Ahora considere exportar de SciPy a MATLAB:


 import numpy as np vect = np.arange (10) vect.shape 

 (10,) 

 sio.savemat ('np_vector.mat', {'vect': vect}) 

Importe el archivo Python a Octave:


 octave:8> load np_vector.mat octave:9> vect vect = 0 1 2 3 4 5 6 7 8 9 octave:10> size(vect) ans = 1 10 

Para verificar el contenido del archivo MATLAB sin leer los datos en la memoria, use el comando whosmat:


 sio.whosmat ('octave_a.mat') 

 [('a', (1, 3, 4), 'double')] 

La función whosmat devuelve una lista de tuplas, una para cada matriz (u otro objeto) que está contenida en el archivo MATLAB. Cada tupla contiene un nombre, contenido de archivo y tipo de datos.


Estructuras de MATLAB


Las estructuras de MATLAB son similares a los diccionarios dictados de Python. La diferencia es que el nombre del campo debe ser una cadena. El valor del campo puede ser cualquier objeto.
Recuerde que MATLAB es un acrónimo de MATrix LABoratory. Porque El objetivo principal de MATLAB es trabajar con matrices, por lo que todos los objetos que contiene son matrices. Incluso un solo número se representa como una matriz de tamaño (1, 1).


 octave:11> my_struct = struct('field1', 1, 'field2', 2) my_struct = { field1 = 1 field2 = 2 } octave:12> save -6 octave_struct.mat my_struct 

Descargue la estructura MATLAB en Python:


 mat_contents = sio.loadmat('octave_struct.mat') mat_contents 

 {'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.2.2, 2019-02-02 20:34:26 UTC', '__version__': '1.0', '__globals__': [], 'my_struct': array([[(array([[1.]]), array([[2.]]))]], dtype=[('field1', 'O'), ('field2', 'O')])} 

 oct_struct = mat_contents['my_struct'] oct_struct.shape 

 (1, 1) 

 val = oct_struct[0,0] val 

 (array([[1.]]), array([[2.]])) 

 val['field1'] 

 array([[1.]]) 

 val['field2'] 

 array([[2.]]) 

 val.dtype 

 dtype([('field1', 'O'), ('field2', 'O')]) 

En las versiones de SciPy de 0.12.0, las estructuras de MATLAB se devuelven como matrices estructuradas numpy. Los nombres de campo de la matriz numpy son los nombres de los campos en la estructura MATLAB. Los nombres de campo se pueden leer con el comando dtype, como en el ejemplo anterior. Obtenga más información sobre los tipos de datos de matrices estructuradas .


Por lo tanto, en MATLAB, una matriz de estructuras tiene un tamaño de al menos 2D, que se repite al leer en SciPy. Para reducir la dimensión a 1, use el parámetro squeeze_me:


 mat_contents = sio.loadmat ('octave_struct.mat', squeeze_me = True) oct_struct = mat_contents ['my_struct'] oct_struct.shape 

 () 

A veces es más conveniente cargar estructuras MATLAB como objetos python en lugar de matrices numpy. Para hacer esto, use el parámetro struct_as_record = False para cargar.


 mat_contents = sio.loadmat ('octave_struct.mat', struct_as_record = False) oct_struct = mat_contents ['my_struct'] oct_struct[0,0].field1 

 array([[1.]]) 

El parámetro struct_as_record = False funciona muy bien junto con el parámetro squeeze_me:


 mat_contents = sio.loadmat('octave_struct.mat', struct_as_record=False, squeeze_me=True) oct_struct = mat_contents['my_struct'] oct_struct.shape #  , ..     shape 

 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-23-d41d0a59bb9b> in <module> 1 mat_contents = sio.loadmat('octave_struct.mat', struct_as_record=False, squeeze_me=True) 2 oct_struct = mat_contents['my_struct'] ----> 3 oct_struct.shape #  , ..   AttributeError: 'mat_struct' object has no attribute 'shape' 

 type(oct_struct) 

 scipy.io.matlab.mio5_params.mat_struct 

 oct_struct.field1 

 1.0 

La forma más fácil de exportar estructuras de python a MATLAB es con diccionarios dictados:


 a_dict = {'field1': 0.5, 'field2': 'a string'} sio.savemat ('saved_struct.mat', {'a_dict': a_dict}) 

En MATLAB se carga como:


 octave:21> load saved_struct octave:22> a_dict a_dict = scalar structure containing the fields: field1 = 0.50000 field2 = a string 

También puede exportar estructuras de python a MATLAB utilizando matrices numpy:


 dt = [('f1', 'f8'), ('f2', 'S10')] arr = np.zeros ((2,), dtype = dt) arr 

 array([(0., b''), (0., b'')], dtype=[('f1', '<f8'), ('f2', 'S10')]) 

 arr [0] ['f1'] = 0.5 arr [0] ['f2'] = 'python' arr [1] ['f1'] = 99 arr [1] ['f2'] = 'not perl' sio.savemat ('np_struct_arr.mat', {'arr': arr}) 

Matrices de células (célula) MATLAB


Las matrices de celdas en MATLAB son como listas de python. Los elementos en las matrices de celdas pueden contener cualquier tipo de objeto MATLAB. Además, las celdas son muy similares a las matrices de objetos numpy. Considere un ejemplo de exportación de una celda de MATLAB a numpy.


 octave:14> my_cells = {1, [2, 3]} my_cells = { [1,1] = 1 [1,2] = 2 3 } octave:15> save -6 octave_cells.mat my_cells 

De vuelta a Python:


 mat_contents = sio.loadmat ('octave_cells.mat') oct_cells = mat_contents ['my_cells'] print (oct_cells.dtype) 

 object 

 val = oct_cells [0,0] val 

 array([[1.]]) 

 print (val.dtype) 

 float64 

Exportaremos de numpy a la matriz de celdas MATLAB usando una matriz de objetos numpy:


 obj_arr = np.zeros ((2,), dtype = np.object) obj_arr [0] = 1 obj_arr [1] = 'a string' obj_arr 

 array([1, 'a string'], dtype=object) 

 sio.savemat ('np_cells.mat', {'obj_arr': obj_arr}) 

Compruebe si la exportación de la celda de numpy a Octave es correcta:


 octave:16> load np_cells.mat octave:17> obj_arr obj_arr = { [1,1] = 1 [2,1] = a string } 

Este es quizás el final. Espero para alguien que este artículo sirva como una razón para integrar la investigación en MATLAB con el software libre.
Fuente: documentación scipy

Source: https://habr.com/ru/post/438600/


All Articles