Python结构如Matlab

时间:2015-12-03 20:01:18

标签: python matlab numpy scipy

我似乎找到了很多黑客的答案,没有标准化的'回答这个问题。我正在寻找在Python中实现Matlab的结构,特别是具有以下两个功能:

  1. 在struct'中,访问字段值' a'使用点表示法(即s.a)
  2. 动态创建字段,无需初始化dtype格式(即s.b = np.array([1,2,3,4]))
  3. 在Python中没有办法做到这一点吗?到目前为止,我找到的唯一解决方案是here,使用虚拟类structtype()。这有效,但感觉有点hackish。 我也想过scipy会暴露它的mat_struct,在loadmat()中使用,但我找不到它的公共接口。 其他人做什么?我不太担心这个结构的性能,它更方便。

3 个答案:

答案 0 :(得分:4)

如果你在3.3及以上,那就是types.SimpleNamespace。除此之外,空课可能是你最好的选择。

答案 1 :(得分:2)

最简单,最直观,最相似的Python实现方法是使用type来实例化一个临时类。它实际上类似于创建一个虚拟类,但我认为它在语义上更清楚地表达了类似于struct的对象的意图。

>>> s = type('', (), {})()
>>> s.a = 4
>>> s.a
4

这里,type用于创建一个无名的类(因此'')没有基础(或父类,由空元组指示),没有默认的类属性(空字典)和最终{ {1}}实例化类/结构。请记住,传递给字典的值不会显示在实例的()属性中,但这个事实可能与您无关。此方法也适用于Python的旧版本(<3.x)。

答案 2 :(得分:0)

在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最初只有2d matricies。然后他们扩展它以允许更高的尺寸。添加了cells,具有相同的2d字符,但允许不同的内容。添加了structures,允许'命名'属性。最初的MATLAB类系统是基于结构构建的(只是将某些函数链接到特定的类结构)。 MATLAB现在已进入第二代系统。

Python从类,词典和列表开始。使用与MATLAB结构相同的.语法访问对象属性。带键的字典(通常,但不总是字符串)。列表以整数索引,并始终允许不同的内容(如cells)。使用成熟的对象类系统,可以在Python中构建更复杂的数据结构,尽管访问仍受基本Python语法的控制。

numpy添加了n维数组。子类np.matrix始终为2d,以旧式MATLAB矩阵为模型。数组总是具有相同类型的元素。但是dtype=object数组包含指向Python对象的指针。在许多方面,它们只是带有数组包装器的Python列表。它们接近MATLAB单元格。

numpy也有结构化数组,其中dtypefields组成。 fields按名称访问。 np.recarray是一个结构化数组,增加了使用.语法访问字段的功能。这使得它们看起来很像MATLAB结构数组。