scipy 并保存mat文件(.mat matlab数据文件)结构

scipy and preserving mat file (.mat matlab data file) structure

参考 scipy 和 numpy 文档一天半后,我尝试这样做 -

dt = {'names':[u'OSversInt',u'Desc',u'OSversStr',\
... u'OSname',u'platform',u'Board'],\
...'formats':['O','O','O','O','O','O']}

aa = np.array([[ np.array([[ ([[15]],[u''],[u'5.0,1'],\
... [u'Android'],[u'main'],[u'MSM8960'])]], np.dtype(dt))]]\
... ,np.dtype(object))

预期结果:

预期,因为当我这样做时

aa = scipy.io.loadmat('file.mat')

产生以下结果。

aa = array([[ array([[ ([[15]], [], [u'5.0.1'], [u'Android'], [u'main'], [u'MSM8960'])]], 
          dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSversStr', 'O'),
    ('OSname', 'O'), ('platform', 'O'), ('Board', 'O')])]], dtype=object)

实际结果 -

array([[[[ ([[15]], [u''], [u'5.0.1'], [u'Android'], [u'main']
,[u'MSM8960'])]]]], dtype=object)

如何使实际结果与预期结果相符? 这对于保留现有的 mat 文件结构至关重要。

根据 看来您可能正在寻找

aa = np.empty((1,1), dtype='O')
aa[0,0] = np.array([[ ([[15]], [], [u'5.0.1'], [u'Android'], [u'main'], [u'MSM8960'])]], 
          dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSversStr', 'O'),
                 ('OSname', 'O'), ('platform', 'O'), ('Board', 'O')])

产生

In [39]: aa
Out[39]: 
array([[ array([[([[15]], [], [u'5.0.1'], [u'Android'], [u'main'], [u'MSM8960'])]], 
      dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSversStr', 'O'), ('OSname', 'O'), ('platform', 'O'), ('Board', 'O')])]], dtype=object)

当您想在 NumPy 数组中放置任意 Python 对象(例如 NumPy 数组或列表)时,dtype 必须是 object。在这种情况下,np.array 的构造失败,因为此函数 interprets inner sequences(元组除外)作为要递归的值而不是作为原子元素。

所以创建这些嵌套对象数组的技巧是首先创建外部对象数组:

aa = np.empty((1,1), dtype='O')

然后在 将所需的值分配给数组的单元格

aa[0,0] = ...

请注意,dtype object 的嵌套 NumPy 数组不允许您使用 NumPy 的快速(主要是数字)函数的优势。他们基本上有 与它们包含的 Python 对象相同的内存占用,并且在性能方面 它们通常并不比普通的 Python 列表列表好。

在 Octave 中,我创建了一个带有结构对象的单元格:

octave:14> y={x}
y = 
{
  [1,1] =

    scalar structure containing the fields:

      OSversInt =  15
      Desc = 
      OSverStr = 5.0.1
      OSname = Android

}
octave:15> save stack32723802.mat -V7 y

numpy 中,我将其加载为:

In [376]: L=loadmat('stack32723802.mat')
In [377]: L['y']
Out[377]: 
array([[ array([[([[15.0]], [], ['5.0.1'], ['Android'])]], 
      dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSverStr', 'O'), ('OSname', 'O')])]], 
      dtype=object)

这是一个二维对象数组 (1,1),只有一个项目,也是二维 (1,1),具有复合数据类型。

In [390]: y=L['y']
In [391]: y[0,0]
Out[391]: 
array([[([[15.0]], [], ['5.0.1'], ['Android'])]], 
      dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSverStr', 'O'), ('OSname', 'O')])

In [392]: y[0,0][0,0]
Out[392]: ([[15.0]], [], ['5.0.1'], ['Android'])

In [394]: y[0,0]['OSversInt']
Out[394]: array([[array([[ 15.]])]], dtype=object)

In [395]: y[0,0]['OSname']
Out[395]: 
array([[array(['Android'], 
      dtype='<U7')]], dtype=object)

4d 'actual outcome' 是 np.array 产生它所能产生的最高维数组的结果。

首先创建内部结构化数组:

In [405]: dt=y.item().dtype
In [406]: item=([[15.0]], [], ['5.0.1'], ['Android'])
In [407]: array1 = np.array([[item]], dtype=dt)
In [408]: array1
Out[408]: 
array([[([[15.0]], [], ['5.0.1'], ['Android'])]], 
      dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSverStr', 'O'), ('OSname', 'O')])

如果我只是将它包装在一个 2d 对象数组中,我得到一个 4d 数组:

In [409]: np.array([[array1]], dtype=object)
Out[409]: array([[[[([[15.0]], [], ['5.0.1'], ['Android'])]]]], dtype=object)

但是如果我创建一个空的二维对象数组,并插入这个内部数组,我会得到与 loadmat 结果相匹配的东西:

In [410]: z=np.empty((1,1),dtype=object)
In [411]: z[0,0]=np.array([[item]], dtype=dt)
In [412]: z
Out[412]: 
array([[ array([[([[15.0]], [], ['5.0.1'], ['Android'])]], 
      dtype=[('OSversInt', 'O'), ('Desc', 'O'), ('OSverStr', 'O'), ('OSname', 'O')])]], dtype=object)