文件IO (scipy.io )

MATLAB文件

loadmat \(文件_名称[, mdict, appendmat] )

加载MATLAB文件。

savemat \(文件_名称,mdict[, appendmat, ...] )

将名称和数组的字典保存到MATLAB样式的.mat文件中。

whosmat \(文件_名称[, appendmat] )

列出MATLAB文件中的变量。

基本功能

我们将从进口开始 scipy.io 并将其称为 sio 为方便起见,请执行以下操作:

>>> import scipy.io as sio

如果您使用的是IPython,请尝试使用Tab-Complete On sio 。在众多选项中,您将发现:

sio.loadmat
sio.savemat
sio.whosmat

这些是您在使用MATLAB文件时最有可能使用的高级函数。您还可以找到::

sio.matlab

这就是从它出发的包裹 loadmatsavemat ,以及 whosmat 都是进口的。在 sio.matlab ,您会发现 mio 模块此模块包含 loadmatsavemat 使用。你可能会时不时地发现自己在重复使用这台机器。

我该怎么开始呢?

你可能会有一个 .mat 您想要读入本网站的文件。或者,您希望将一些变量从SciPy/NumPy传递到MATLAB。

为了节省使用MATLAB许可的时间,让我们从 Octave. OCTIVE具有与MATLAB兼容的保存和加载功能。开始倍频程 (octave 在我的命令行中):

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:

>>> mat_contents = sio.loadmat('octave_a.mat')
>>> mat_contents
{'a': array([[[  1.,   4.,   7.,  10.],
        [  2.,   5.,   8.,  11.],
        [  3.,   6.,   9.,  12.]]]),
 '__version__': '1.0',
 '__header__': 'MATLAB 5.0 MAT-file, written by
 Octave 3.6.3, 2013-02-17 21:02:11 UTC',
 '__globals__': []}
>>> 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)

现在让我们试试另一种方式:

>>> import numpy as np
>>> vect = np.arange(10)
>>> vect.shape
(10,)
>>> sio.savemat('np_vector.mat', {'vect':vect})

然后回到八度音阶:

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结构有点像Python字典,只是字段名必须是字符串。任何MATLAB对象都可以是字段的值。对于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中:

>>> mat_contents = sio.loadmat('octave_struct.mat')
>>> mat_contents
{'my_struct': array([[([[1.0]], [[2.0]])]],
      dtype=[('field1', 'O'), ('field2', 'O')]), '__version__': '1.0', '__header__': 'MATLAB 5.0 MAT-file, written by Octave 3.6.3, 2013-02-17 21:23:14 UTC', '__globals__': []}
>>> oct_struct = mat_contents['my_struct']
>>> oct_struct.shape
(1, 1)
>>> val = oct_struct[0,0]
>>> val
([[1.0]], [[2.0]])
>>> val['field1']
array([[ 1.]])
>>> val['field2']
array([[ 2.]])
>>> val.dtype
dtype([('field1', 'O'), ('field2', 'O')])

在从0.12.0开始的SciPy版本中,MATLAB结构返回为NumPy结构化数组,其中的字段以结构字段命名。您可以在 dtype 上面的输出。另请注意:

>>> val = oct_struct[0,0]

以及:

octave:13> size(my_struct)
ans =

   1   1

因此,在MATLAB中,结构数组必须至少是二维的,当我们读取到SciPy时,我们会复制这一点。如果要挤出所有长度为1的维度,请尝试以下操作:

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

有时,将MATLAB结构作为Python对象加载比将NumPy结构化数组加载更方便-这可以使Python中的访问语法与MATLAB中的更相似。为此,请使用 struct_as_record=False 参数设置为 loadmat

>>> 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 # but no - it's a scalar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'mat_struct' object has no attribute 'shape'
>>> type(oct_struct)
<class 'scipy.io.matlab.mio5_params.mat_struct'>
>>> oct_struct.field1
1.0

可以通过各种方式保存结构数组。一种简单的方法是使用DICTS:

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

加载方式为:

octave:21> load saved_struct
octave:22> a_dict
a_dict =

  scalar structure containing the fields:

    field2 = a string
    field1 =  0.50000

您还可以将结构再次保存回MATLAB(在我们的示例中为Octave),如下所示:

>>> dt = [('f1', 'f8'), ('f2', 'S10')]
>>> arr = np.zeros((2,), dtype=dt)
>>> arr
array([(0.0, ''), (0.0, '')],
      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对象数组,这就是我们将它们加载到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

保存到MATLAB单元格数组只需要创建一个NumPy对象数组:

>>> 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})
octave:16> load np_cells.mat
octave:17> obj_arr
obj_arr =
{
  [1,1] = 1
  [2,1] = a string
}

IDL文件

readsav \(文件_名称[, idict, python_dict, ...] )

读取IDL.sav文件。

矩阵市场文件

mminfo \(源)

从Matrix Market返回大小和存储参数,类似于“源”。

mmread \(源)

将类似于矩阵市场文件的“源”内容读取到矩阵中。

mmwrite \(目标,一个[, comment, field, ...] )

写入稀疏或密集数组 a 向矩阵市场文件一样 target

wav声音文件 (scipy.io.wavfile )

read \(文件名[, mmap] )

打开WAV文件。

write \(文件名,速率,数据)

将NumPy数组编写为wav文件。

ARFF文件 (scipy.io.arff )

loadarff \(F)

读取ARFF文件。

Netcdf

netcdf_file \(文件名[, mode, mmap, version, ...] )

NetCDF数据的文件对象。

允许读取NetCDF文件(版本为 pupynere 包)