SciPy,在MATLAB中输入和输出


SciPy(发音为sai pie)是基于Numpy Python扩展的数学应用程序包。 借助SciPy,交互式Python会话可为复杂系统(如MATLAB,IDL,Octave,R-Lab和SciLab)转变为相同的完整数据处理和原型开发环境。 在本文中,我想谈谈scipy.io I / O包的功能,该包允许您使用Octave和MATLAB数据文件。


引言


首先,按如下所示导入scipy.io包:


import scipy.io as sio 

scipy.io包的主要过程,使您可以使用MATLAB文件:


 sio.loadmat sio.savemat sio.whosmat 

为了不违反MATLAB许可协议,我们将在GNU Octave环境中工作,该环境具有与MATLAB兼容的保存和加载功能。 在八度提示下,输入:


 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 

在Python中导入MATLAB文件的代码:


 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) 

如您所见,文件已正确读取。 现在考虑从SciPy导出到MATLAB:


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

 (10,) 

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

将Python文件导入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 

要检查MATLAB文件的内容而不读取内存中的数据,请使用whosmat命令:


 sio.whosmat ('octave_a.mat') 

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

whosmat函数返回一个元组列表,每个元组用于MATLAB文件中包含的每个数组(或其他对象)。 每个元组包含一个名称,文件内容和数据类型。


MATLAB结构


MATLAB的结构类似于Python字典。 区别在于字段名称必须是字符串。 字段值可以是任何对象。
回想一下,MATLAB是MATrix LABoratory的首字母缩写。 因为 MATLAB的主要目的是使用矩阵,因此其中的所有对象都是矩阵。 甚至单个数字也表示为大小(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 

下载Python中的MATLAB结构:


 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')]) 

在0.12.0版的SciPy版本中,MATLAB结构以numpy结构化数组的形式返回。 numpy数组的字段名称是MATLAB结构中的字段名称。 如上例所示,可以使用dtype命令读取字段名称。 了解有关结构化数组数据类型的更多信息。


因此,在MATLAB中,结构数组的大小至少为2D,在SciPy中读取时会重复。 要将尺寸减小为1,请使用squeeze_me参数:


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

 () 

有时将MATLAB结构作为python对象而不是numpy数组加载会更加方便。 为此,请使用struct_as_record = False参数加载。


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

 array([[1.]]) 

struct_as_record = False参数与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 

将结构从python导出到MATLAB的最简单方法是使用dicts字典:


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

在MATLAB中,它的加载方式为:


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

您还可以使用numpy数组将结构从python导出到MATLAB:


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

细胞阵列(细胞)MATLAB


MATLAB中的单元格数组类似于python列表。 单元阵列中的元素可以包含任何类型的MATLAB对象。 而且,单元格与numpy对象的数组非常相似。 考虑一个将单元从MATLAB导出到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 

返回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 

我们将使用一个numpy对象数组从numpy导出到单元格数组MATLAB:


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

检查从numpy到Octave的单元格导出是否正确:


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

到此为止。 我希望这篇文章能成为将研究与免费软件集成到MATLAB中的借口。
资料来源: scipy文档

Source: https://habr.com/ru/post/zh-CN438600/


All Articles