文件 IO (scipy.io
)#
另请参阅
MATLAB 文件#
|
加载 MATLAB 文件。 |
|
将名称和数组的字典保存到 MATLAB 样式的 .mat 文件中。 |
|
列出 MATLAB 文件中的变量。 |
基本函数#
我们将首先导入 scipy.io
并为了方便起见将其称为 sio
>>> import scipy.io as sio
如果您正在使用 IPython,请尝试在 sio
上使用 Tab 键补全。在众多选项中,您会发现
sio.loadmat
sio.savemat
sio.whosmat
这些是您在处理 MATLAB 文件时最有可能使用的高级函数。您还会发现
sio.matlab
这是从中导入 loadmat
、savemat
和 whosmat
的包。在 sio.matlab
中,您将找到 mio
模块。该模块包含 loadmat
和 savemat
使用的机制。有时您可能会发现自己重复使用这种机制。
我该如何开始?#
您可能有一个想要读取到 SciPy 中的 .mat
文件。或者,您想将一些变量从 SciPy / NumPy 传递到 MATLAB。
为了避免使用 MATLAB 许可证,让我们从 Octave 开始。Octave 具有与 MATLAB 兼容的保存和加载功能。启动 Octave(在我的命令行中输入 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
{'__header__': b'MATLAB 5.0 MAT-file, written
by Octave 3.2.3, 2010-05-30 02:13:40 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)
现在让我们尝试反过来
>>> import numpy as np
>>> vect = np.arange(10)
>>> vect.shape
(10,)
>>> sio.savemat('np_vector.mat', {'vect':vect})
然后回到 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 结构体有点像 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
{'__header__': b'MATLAB 5.0 MAT-file, written by Octave 3.2.3, 2010-05-30 02:00: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
np.void((array([[1.]]), array([[2.]])), dtype=[('field1', 'O'), ('field2', 'O')])
>>> val['field1']
array([[ 1.]])
>>> val['field2']
array([[ 2.]])
>>> val.dtype
dtype([('field1', 'O'), ('field2', 'O')])
在 SciPy 0.12.0 及更高版本中,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
保存结构体数组可以通过多种方式完成。一种简单的方法是使用字典
>>> 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=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 文件#
|
读取 IDL .sav 文件。 |
矩阵市场文件#
|
从类似文件的“source”的矩阵市场文件中返回大小和存储参数。 |
|
将类似文件的“source”的矩阵市场文件的内容读取到矩阵中。 |
|
将稀疏或密集数组 a 写入类似文件的矩阵市场 target。 |
Wav 声音文件 (scipy.io.wavfile
)#
|
打开 WAV 文件。 |
|
将 NumPy 数组写入为 WAV 文件。 |
Arff 文件 (scipy.io.arff
)#
|
读取 arff 文件。 |
Netcdf#
|
用于 NetCDF 数据的文件对象。 |
允许读取 NetCDF 文件(pupynere 包的版本)