我在 Octave 中做到了:
octave:2> x.a = 1;
octave:3> x.b = [1, 2; 3, 4];
octave:4> x.c = "string";
octave:7> save -7 test.mat x
在 ipython (2.7) 中:
In [27]: from scipy.io import loadmat
In [28]: A=loadmat('test.mat')
In [29]: A
Out[29]:
{'__globals__': [],
'__header__': 'MATLAB 5.0 MAT-file, written by Octave 3.8.2, 2015-12-04 02:57:47 UTC',
'__version__': '1.0',
'x': array([[([[1.0]], [[1.0, 2.0], [3.0, 4.0]], [u'string'])]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O')])}
在这种情况下,A['x'] 是一个 numpy 结构化数组,具有 3 个 dtype=object 字段。
In [33]: A['x']['b'][0,0]
Out[33]:
array([[ 1., 2.],
[ 3., 4.]])
In [34]: A['x'][0,0]
Out[34]: ([[1.0]], [[1.0, 2.0], [3.0, 4.0]], [u'string'])
In [35]: A['x'][0,0]['b']
Out[35]:
array([[ 1., 2.],
[ 3., 4.]])
由于 x 来自 MATLAB,我必须使用 [0,0] 对其进行索引。
octave:9> size(x)
ans =
1 1
我可以使用不同的开关加载A,并使用.b 格式访问属性:
In [62]: A=loadmat('test.mat',struct_as_record=False)
In [63]: A['x'][0,0].b
Out[63]:
array([[ 1., 2.],
[ 3., 4.]])
在这种情况下,A['x'] 的元素是 <scipy.io.matlab.mio5_params.mat_struct at 0x9bed76c> 类型
一些历史可能会有所帮助。 MATLAB 最初只有二维矩阵。然后他们扩展它以允许更高的维度。 cells 被添加,具有相同的 2d 字符,但允许不同的内容。 structures 已添加,允许“命名”属性。最初的 MATLAB 类系统是建立在结构上的(只需将某些函数链接到特定的类结构)。 MATLAB 现在处于其第二代类系统中。
Python 从类、字典和列表开始。使用与 MATLAB 结构相同的 . 语法访问对象属性。带键的字典(通常,但不总是字符串)。用整数索引的列表,并且总是允许不同的内容(如cells)。借助成熟的对象类系统,可以在 Python 中构建更精细的数据结构,尽管访问仍然受基本 Python 语法的约束。
numpy 添加 n 维数组。子类np.matrix 始终是二维的,以旧式 MATLAB 矩阵为模型。数组总是具有相同种类的元素。但是dtype=object 数组包含指向 Python 对象的指针。在许多方面,它们只是带有数组包装器的 Python 列表。它们靠近 MATLAB 单元。
numpy 也有结构化数组,有一个复合 dtype,由 fields 组成。 fields 按名称访问。 np.recarray 是一个结构化数组,增加了使用 . 语法访问字段的能力。这使它们看起来很像 MATLAB 结构数组。