您的位置:

Python工程师必备之scipy.io.savemat用法详解

如果你正在做数据科学或机器学习方面的工作,那么你一定已经接触过MATLAB或从同事那里接收了MATLAB格式的数据文件。那么如何在Python环境中读写这些文件呢?scipy底下的io模块是非常好的选择。Scipy是一个Python开发的科学计算库,它包括高效率的数组操作,线性代数,傅里叶变换和优化算法。而IO模块作为Scipy框架的子模块,提供了各种阅读和写入数据的方法。

一、savemat概述

保存.mat文件中的数据的常用函数是savemat函数,它的完整语法如下所示:

scipy.io.savemat(file_name, mdict, appendmat=True, format='5', long_field_names=False, do_compression=False, oned_as='row')

参数含义如下:

  • file_name:字符串,包含路径或完整文件名的字符串以保存数据。MATLAB文件的扩展名应为.mat。
  • mdict:变量字典或类似对象。所有必须为字符串的键名将转换为字符向量,并保存在MATLAB 5格式保存的内容中。
  • appendmat:布尔值,可选。如果为True,则支持附加多个变量和对象到相同的MATLAB文件,可以使用loadmat再次加载数据,默认为True。
  • format:字符串,可选,指定MATLAB格式版本。支持'4'(MATLAB 4格式 - Level 1.0),'5'(MATLAB 5格式 - Level 2.0)和'5加'(MATLAB 5格式 - Level 2.0,使用HDF5)。默认值为'5'(即MATLAB 5格式 - Level 2.0)。
  • long_field_names:布尔值,可选。是否使用长名称,其长度大于限制长度的数据将被转换为struct,而不是数组。默认值为False。
  • do_compression:布尔值,可选。是否使用压缩。默认为False(即不压缩)。如果设置为True,则使用gzip进行压缩。
  • oned_as:{'row','col'},可选。MATLAB 1-D数组作为行向量或列向量存储。默认值为'row'。

二、使用实例

1、基本处理步骤

我们将以一个简单的例子来说明savemat函数。文件名为mydata.mat的.mat文件将存储包含两个数组A和B的Python字典。代码如下:

import scipy.io as sio
import numpy as np

A = np.arange(0, 10, 2)      # 创建数组A
B = np.random.randn(3, 3)    # 创建数组B

# 将数据保存到MATLAB格式文件
sio.savemat('mydata.mat', {'A': A, 'B': B})

字典中的键是变量名,值则是Numpy数组对象。这些对象将存储在MATLAB文件中。在读取此文件时,其他Python代码可能会使用如下命令:

import scipy.io as sio

data = sio.loadmat('mydata.mat')
A = data['A']
B = data['B']

2、加入时间戳

具有时间戳的文件名对于跟踪您的文件非常有用,下面就是一个例子。函数strftime将时间日期转换成人类友好的字符串形式。代码如下:

import scipy.io as sio
import numpy as np
import time

timestamp = time.strftime('%Y_%m_%d_%H_%M')    # 创建一个时间戳

A = np.arange(0, 10, 2)      # 创建数组A
B = np.random.randn(3, 3)    # 创建数组B

# 将数据保存到文件
sio.savemat(f'data_{timestamp}.mat', {'A': A, 'B': B})

3、数据压缩

波形文件和图像通常非常大,压缩可以显著减少文件大小,可以通过设置do_compression参数为True 来使用gzip压缩。代码如下:

import scipy.io as sio
import numpy as np

A = np.arange(0, 200, 2)        # 创建一个长度为100的数组A
B = np.random.randn(500, 500)   # 创建一个500*500的数组B

# 将数据保存到文件
sio.savemat('mydata.mat', {'A': A, 'B': B}, do_compression=True)

将do_compression参数设置为True来使用gzip压缩。在读取此文件时,其他Python代码可能会使用如下命令:

import scipy.io as sio

data = sio.loadmat('mydata.mat')
A = data['A']
B = data['B']

三、savemat与loadmat

在使用Scipy进行读写MATLAB格式数据文件时,由于函数savemat和loadmat是两个模块,因此在使用时需要引入相应的模块。这两个函数的功能都非常简单,经常被使用。我们已经介绍了如何使用savemat,现在让我们来看一看loadmat函数的使用。

要从MATLAB文件中读取数据,可以使用scipy.io.loadmat函数来加载MATLAB格式的文件,并返回一个Python变量字典。假设我们的例子文件mydata.mat包含两个名为'A'和'B'的变量,则可以按如下方式读取数据:

import scipy.io as sio

data = sio.loadmat('mydata.mat')
A = data['A']
B = data['B']

注意,loadmat在读取数据时,将文件中的所有变量存储在Python变量字典中。由此导致的一个问题是,变量名称为字符串,但在访问Python字典时,必须进行转换。因此,如果我们使用loadmat读取MATLAB文件中的变量,则可以通过遍历Python字典来访问这些变量:

import scipy.io as sio

data = sio.loadmat('mydata.mat')

for var in data:
    if not var.startswith('__'):
        exec(f"{var}=data['{var}']")

需要注意的是,这种方式在Python中使用了非常强大的exec()函数,必须小心使用。因此,更保险的做法是使用类似于下面的方式来访问Python字典中的变量:

import scipy.io as sio

data = sio.loadmat('mydata.mat')
A = data['A'].flatten()
B = data['B']

前面的代码说明了如何使用Scipy保存和读取MATLAB格式数据文件。此外,当需要进行多个Python程序间的交互式协作时,使用MATLAB文件将非常方便。当然,Matplotlib和Pandas等流行的科学计算包都可以读取和写入MATLAB文件。