SciPy, entrada e saída em MATLAB


SciPy (pronuncia-se sai pie) é um pacote de aplicativos matemáticos baseado na extensão Numpy Python. Com o SciPy, uma sessão interativa em Python se transforma no mesmo ambiente completo de processamento e prototipagem de dados para sistemas complexos como MATLAB, IDL, Octave, R-Lab e SciLab. Neste post, gostaria de falar sobre as possibilidades do pacote de E / S do scipy.io, que permite trabalhar com arquivos de dados Octave e MATLAB.


1. Introdução


Primeiro, importe o pacote scipy.io da seguinte maneira:


import scipy.io as sio 

Os principais procedimentos do pacote scipy.io que permitem trabalhar com arquivos MATLAB:


 sio.loadmat sio.savemat sio.whosmat 

Para não violar o contrato de licença do MATLAB, trabalharemos no ambiente GNU Octave, que possui funções de salvar e carregar compatíveis com o MATLAB. No prompt Octave, digite:


 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 o arquivo MATLAB em 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 você pode ver, o arquivo foi lido corretamente. Agora considere exportar do SciPy para o MATLAB:


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

 (10,) 

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

Importe o arquivo Python para o 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 o conteúdo do arquivo MATLAB sem ler os dados na memória, use o comando whosmat:


 sio.whosmat ('octave_a.mat') 

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

A função whosmat retorna uma lista de tuplas, uma para cada matriz (ou outro objeto) contida no arquivo MATLAB. Cada tupla contém um nome, conteúdo do arquivo e tipo de dados.


Estruturas MATLAB


As estruturas do MATLAB são semelhantes aos dicionários de dicionários do Python. A diferença é que o nome do campo deve ser uma sequência. O valor do campo pode ser qualquer objeto.
Lembre-se de que MATLAB é um acrônimo para MATrix LABoratory. Porque o principal objetivo do MATLAB é trabalhar com matrizes, portanto todos os objetos nele são matrizes. Até um único número é representado como uma matriz de tamanho (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 

Faça o download da estrutura do MATLAB em 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')]) 

Nas versões SciPy de 0.12.0, as estruturas MATLAB são retornadas como matrizes estruturadas numpy. Os nomes dos campos da matriz numpy são os nomes dos campos na estrutura MATLAB. Os nomes dos campos podem ser lidos usando o comando dtype, como no exemplo acima. Saiba mais sobre os tipos de dados de matrizes estruturadas .


Assim, no MATLAB, uma matriz de estruturas tem um tamanho de pelo menos 2D, que é repetido ao ler no SciPy. Para reduzir a dimensão para 1, use o parâmetro squeeze_me:


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

 () 

Às vezes, é mais conveniente carregar estruturas MATLAB como objetos python, em vez de matrizes numpy. Para fazer isso, use o parâmetro struct_as_record = False para carregar.


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

 array([[1.]]) 

O parâmetro struct_as_record = False funciona muito bem em conjunto com o 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 

A maneira mais fácil de exportar estruturas de python para MATLAB é com dicionários dict:


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

No MATLAB, ele carrega como:


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

Você também pode exportar estruturas de python para MATLAB usando matrizes 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}) 

Matrizes de células (célula) MATLAB


Matrizes de células no MATLAB são como listas de python. Os elementos nas matrizes de células podem conter qualquer tipo de objeto MATLAB. Além disso, as células são muito semelhantes às matrizes de objetos numpy. Considere um exemplo de exportação de uma célula do MATLAB para 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 volta ao 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 para o array de células MATLAB usando um array numpy de objetos:


 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}) 

Verifique se a exportação da célula de numpy para o Octave está correta:


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

Este é talvez o fim. Espero que este artigo sirva de pretexto para integrar a pesquisa no MATLAB com o software livre.
Fonte: documentação scipy

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


All Articles