Skip to content

SciPy - 输入与输出

scipy.io 包提供了一套功能强大的函数,用于读写各种文件格式。这对于不同软件环境之间的数据交换或科学数据的持久化存储至关重要。支持的一些格式包括:

  • MATLAB (.mat 文件)
  • IDL (Interactive Data Language 文件)
  • Matrix Market (.mtx 文件)
  • Wave 音频文件 (.wav)
  • ARFF (Attribute-Relation File Format)
  • NetCDF (Network Common Data Form)
  • 以及其他。对于非常大的数据集或更复杂的层次结构数据,可以考虑使用 HDF5 库(如 h5py 或 tables)。

让我们重点介绍科学数据交换中最常用的一种格式:MATLAB 文件。

SciPy 提供了从 MATLAB 的 .mat 文件格式加载数据和将数据保存为该格式的函数。这在与 MATLAB 用户协作或使用现有 MATLAB 数据时特别有用。

函数描述
scipy.io.loadmat()将 .mat 文件加载到 Python 字典中。.mat 文件中的变量成为字典的键(key)。
scipy.io.savemat()将包含变量名和 NumPy 数组(或其他兼容数据类型)的字典保存到 .mat 文件中。
scipy.io.whosmat()列出 .mat 文件中存储的变量,而无需将整个文件加载到内存中。返回一个元组列表,每个元组包含变量名、其形状(shape)和数据类型(data type)。

让我们看一个保存和加载 .mat 文件的例子:

import scipy.io as sio
import numpy as np
# Create a NumPy array
my_array = np.arange(15).reshape(3, 5)
# Data to save: a dictionary where keys are variable names for MATLAB
data_to_save = {'my_matrix': my_array, 'my_scalar': 42.0}
# Save data to a .mat file
file_path = 'my_data.mat'
sio.savemat(file_path, data_to_save)
print(f"Data saved to {file_path}")
# Now, load the .mat file
loaded_data = sio.loadmat(file_path)
print("\nContent of the loaded .mat file:")
# The loaded data is a dictionary. Let's inspect it.
for key, value in loaded_data.items():
print(f"Variable name: {key}")
if isinstance(value, np.ndarray):
print(f"Type: {type(value)}, Shape: {value.shape}, Dtype: {value.dtype}")
print(f"Data:\n{value}")
else:
print(f"Type: {type(value)}, Value: {value}")
print("---")
# Access a specific variable
loaded_array = loaded_data['my_matrix']
print(f"\nAccessed 'my_matrix':\n{loaded_array}")

此程序的输出将类似于(确切的元信息可能会有所不同):

Data saved to my_data.mat
Content of the loaded .mat file:
Variable name: __header__
Type: <class 'bytes'>, Value: b'MATLAB 5.0 MAT-file, Platform: ...'
---
Variable name: __version__
Type: <class 'str'>, Value: 1.0
---
Variable name: __globals__
Type: <class 'list'>, Value: []
---
Variable name: my_matrix
Type: <class 'numpy.ndarray'>, Shape: (3, 5), Dtype: int64
Data:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
---
Variable name: my_scalar
Type: <class 'numpy.ndarray'>, Shape: (1, 1), Dtype: float64
Data:
[[42.]]
---
Accessed 'my_matrix':
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]

请注意,loadmat 返回一个包含您保存的变量以及一些元数据(如 __header__、__version__、__globals__)的字典。标量(scalar)通常被加载为二维数组;您可以在 loadmat 中使用 squeeze_me=True 将它们转换为零维数组(如果适用)。例如:loaded_data = sio.loadmat(file_path, squeeze_me=True)。

要在不将所有数据读入内存的情况下检查 MATLAB 文件的内容(这对于大文件特别有用),请使用 whosmat:

import scipy.io as sio
# Assuming 'my_data.mat' was created by the previous example
file_path = 'my_data.mat'
variables_info = sio.whosmat(file_path)
print("Variables in the .mat file (name, shape, type):")
for var_name, var_shape, var_type in variables_info:
print(f"- {var_name}: shape={var_shape}, type={var_type}")

此程序的输出将是:

Variables in the .mat file (name, shape, type):
- my_matrix: shape=(3, 5), type=int64
- my_scalar: shape=(1, 1), type=float64

补充说明:处理 .mat 文件时,特别是来自较新 MATLAB 版本(v7.3 及更高版本)的文件,它们可能是基于 HDF5 的。scipy.io.loadmat 可以处理其中许多文件,但对于复杂的结构或非常大的基于 HDF5 的 .mat 文件,使用专用的 HDF5 库(如 h5py)可能提供更多控制。请务必查阅 scipy.io.loadmat 文档,了解诸如 mat_dtype 和 chars_as_strings 等选项,以便根据需要处理数据类型转换。