杰瑞科技汇

Python与MATLAB混合编程如何实现?

核心思想

混合编程的核心是让 Python 和 MATLAB 各自发挥所长:

Python与MATLAB混合编程如何实现?-图1
(图片来源网络,侵删)
  • Python: 负责 Web 后端、数据预处理/后处理、机器学习模型训练与部署、自动化任务、与其他系统集成。
  • MATLAB: 负责复杂的数值计算、算法原型验证、Simulink 仿真、专业的科学绘图、特定领域的工具箱(如信号处理、控制、通信)。

使用 MATLAB Engine API for Python (推荐首选)

这是 MathWorks 官方提供的最直接、最无缝的集成方式,它允许你在 Python 代码中直接调用 MATLAB 函数,并在两者之间自由传递数据。

安装

你需要在你的 MATLAB 安装目录中找到并运行 setup.py 脚本来安装引擎。

# 在 MATLAB 的命令窗口中运行
!cd [你的 MATLAB 安装路径]/extern/engines/python
!python setup.py install

或者,如果你使用 Conda,也可以通过 Conda Forge 安装:

conda install -c conda-forge matlabengine

基本使用

步骤 1:启动 MATLAB 引擎

Python与MATLAB混合编程如何实现?-图2
(图片来源网络,侵删)
import matlab.engine
# 启动一个后台会话
eng = matlab.engine.start_matlab()
# 你也可以指定启动选项,例如不显示图形窗口
# eng = matlab.engine.start_matlab('-desktop')

步骤 2:在 Python 中调用 MATLAB 函数

# 调用 MATLAB 内置函数
eng.sqrt(4.0, nargout=1) # nargout 指定返回参数个数
# 调用 MATLAB 脚本(假设你有一个名为 my_script.m 的文件)
eng.my_script(nargout=0) # 如果脚本没有返回值,使用 nargout=0
# 调用你自己写的 MATLAB 函数
result = eng.my_matlab_function(1, 2, 3, nargout=1)
print(f"MATLAB 函数返回结果: {result}")

步骤 3:在 Python 和 MATLAB 之间传递数据 这是最关键的一步,引擎会自动进行数据类型的转换。

  • Python -> MATLAB:

    • list -> MATLAB cell array
    • dict -> MATLAB struct
    • numpy.ndarray -> MATLAB numeric array (这是最高效的方式)
    • int, float -> MATLAB double
  • MATLAB -> Python:

    Python与MATLAB混合编程如何实现?-图3
    (图片来源网络,侵删)
    • MATLAB numeric array -> numpy.ndarray
    • MATLAB cell array -> Python list ofnumpy.ndarray``
    • MATLAB struct -> Python dict

示例:数据传递

import numpy as np
# 创建一个 NumPy 数组 (Python)
py_array = np.array([[1, 2, 3], [4, 5, 6]])
# 将 NumPy 数组传递给 MATLAB
# MATLAB 会将其视为一个 double 类型的矩阵
mat_matrix = eng.workspace('mat_matrix', py_array)
# 在 MATLAB 中进行计算
eng.eval('result_matrix = mat_matrix * 2;', nargout=0)
# 将结果从 MATLAB workspace 取回 Python
py_result = eng.eval('result_matrix', nargout=1)
print("从 MATLAB 返回的 NumPy 数组:")
print(py_result)
print(type(py_result)) # <class 'numpy.ndarray'>
# 关闭引擎
eng.quit()

优点

  • 无缝集成:数据类型自动转换,非常方便。
  • 高性能:通过 NumPy 数组传递数据,避免了文件 I/O,速度极快。
  • 双向调用:Python 可以调用 MATLAB,MATLAB 也可以通过引擎调用 Python(需要额外配置)。
  • 官方支持:稳定可靠,与 MATLAB 版本更新同步。

缺点

  • 依赖 MATLAB:目标机器上必须安装有 MATLAB 许可证。
  • 环境配置:初次安装引擎步骤稍显繁琐。

适用场景

  • 需要在 Python 流程中频繁、高性能地调用 MATLAB 核心算法的场景。
  • 将现有的 MATLAB 代码集成到 Python 主导的项目中。

通过文件进行数据交换 (简单通用)

这是一种最传统、最通用的方法,Python 将数据写入文件,MATLAB 读取文件进行处理;反之亦然。

基本流程

  1. Python 写入: Python 使用 numpy.savetxt, pandas.DataFrame.to_csv, scipy.io.savemat 等函数将数据保存为文件(如 .txt, .csv, .mat)。
  2. MATLAB 读取: MATLAB 使用 load, readmatrix, csvread 等函数读取该文件。
  3. MATLAB 处理: MATLAB 执行计算。
  4. MATLAB 写出: MATLAB 将结果保存为文件。
  5. Python 读取: Python 读取结果文件。

示例

使用 .mat 文件是最高效的方式,因为它保留了数据类型和结构。

Python 端 (python_script.py)

import numpy as np
from scipy.io import savemat, loadmat
# 1. Python 创建数据
data_to_send = {
    'input_matrix': np.random.rand(5, 5),
    'input_scalar': 10,
    'input_string': 'Hello from Python!'
}
# 2. Python 将数据保存为 .mat 文件
savemat('data_from_python.mat', data_to_send)
print("Python: 数据已保存到 data_from_python.mat")
# 4. (模拟) 等待 MATLAB 处理... (在实际应用中,可能需要用 subprocess 调用)
# 这里我们直接读取 MATLAB 写回的文件
# import time
# time.sleep(2)
# 5. Python 读取 MATLAB 的结果
matlab_result = loadmat('result_from_matlab.mat')
print("Python: 已读取 MATLAB 的结果")
print("MATLAB 返回的矩阵:")
print(matlab_result['output_matrix'])

MATLAB 端 (process_data.m)

% 3. MATLAB 读取 Python 发来的数据
data = load('data_from_python.mat');
% 显示从 Python 接收到的数据
disp('MATLAB: 从 Python 接收到的数据:');
disp(data.input_matrix);
disp(data.input_scalar);
disp(data.input_string);
% 进行一些计算
output_matrix = data.input_matrix * 2 + data.input_scalar;
% 4. MATLAB 将结果保存回 .mat 文件
save('result_from_matlab.mat', 'output_matrix');
disp('MATLAB: 结果已保存到 result_from_matlab.mat');

运行方式 你可以手动运行这两个脚本,或者使用 Python 的 subprocess 模块来自动化调用 MATLAB。

# 在 python_script.py 中添加
import subprocess
# 调用 MATLAB 执行 .m 文件
# 需要确保 MATLAB 在系统 PATH 中,或者提供完整路径
try:
    subprocess.run(['matlab', '-batch', 'process_data'], check=True)
    print("成功调用 MATLAB 执行 process_data.m")
except subprocess.CalledProcessError as e:
    print(f"调用 MATLAB 失败: {e}")
# 然后继续读取结果文件...

优点

  • 简单通用:不依赖任何特殊的 API,任何能读写文件的编程语言都可以实现。
  • 解耦合:Python 和 MATLAB 进程是分离的,一个进程的崩溃不会直接影响另一个。
  • 无需 MATLAB 引擎:接收端不需要安装 MATLAB 引擎(只要能读写文件格式即可)。

缺点

  • 性能瓶颈:文件 I/O 速度远低于内存中的数据交换。
  • 代码复杂:需要额外的文件读写和路径管理逻辑。
  • 异步处理困难:实现同步等待和错误处理比较麻烦。

适用场景

  • 一次性或低频率的数据交换。
  • Python 和 MATLAB 运行在不同机器上的分布式系统。
  • 对性能要求不高的简单任务。

使用 Web 服务 (REST API)

这种方法将 MATLAB 的功能封装成一个 Web 服务(例如使用 MATLAB Production Server),Python 通过 HTTP 请求来调用这个服务。

基本流程

  1. MATLAB 端: 使用 MATLAB Compiler SDK 或 MATLAB Production Server 将一个或多个 MATLAB 函数打包成一个可部署的 Web 应用。
  2. 服务启动: 启动这个 Web 服务,它会监听某个端口。
  3. Python 端: Python 使用 requests 等库向该服务的 API 端点发送 HTTP 请求(通常是 POST,携带 JSON 格式的数据)。
  4. 数据交换: 数据在网络上以 JSON 等格式传输,服务端(MATLAB)处理后再将结果以 JSON 格式返回给客户端(Python)。

优点

  • 跨平台、跨语言:任何能发送 HTTP 请求的语言或设备都可以调用 MATLAB 功能。
  • 可扩展性强:易于实现负载均衡、服务发现和微服务架构。
  • 集中管理:MATLAB 逻辑集中部署在服务器上,便于维护和更新。

缺点

  • 架构复杂:需要部署和管理一个额外的服务器。
  • 网络延迟:HTTP 请求和网络传输会带来额外的延迟。
  • 需要额外工具:需要 MATLAB Compiler SDK 或 MATLAB Production Server,这些是商业产品。

适用场景

  • 企业级应用,需要将 MATLAB 算法作为服务提供给多个客户端(包括 Web 前端、移动 App 等)。
  • 异步计算任务。

使用第三方库 matlab.py

这是一个轻量级的第三方库,它通过在后台运行一个 MATLAB 实例,并通过标准输入/输出进行通信,它类似于方法二(文件交换),但直接在内存中通过文本流通信。

pip install matlab

示例

from matlab import engine
# 启动引擎
eng = engine.start_matlab()
# 调用函数
# 注意:这里的语法和方法一略有不同,更侧重于字符串命令
result = eng.eval("sqrt(16)", nargout=1)
print(result)
# 关闭引擎
eng.quit()

注意:这个库的活跃度和功能通常不如官方的 MATLAB Engine API,对于新项目,强烈推荐优先使用方法一


总结与选择建议

方法 优点 缺点 适用场景
MATLAB Engine API 无缝、高性能、双向调用 依赖 MATLAB 许可,安装稍复杂 首选方案,需要频繁、高性能集成,项目在 MATLAB 可用环境中。
文件交换 简单、通用、解耦合 性能低,代码复杂 低频、一次性数据交换;跨机器、分布式系统。
Web 服务 跨平台、可扩展性强 架构复杂,有网络延迟,需商业工具 企业级服务化部署,多客户端调用。
第三方库 轻量级 功能少,维护可能不及时 快速原型验证,或不便安装官方引擎的特定环境。

最终建议:

  • 如果你的项目主要在 Python 环境中运行,但需要调用一些关键的 MATLAB 函数或算法库,请毫不犹豫地选择 MATLAB Engine API for Python,这是最直接、最高效的方式。
  • 如果你的 Python 和 MATLAB 代码运行在不同的机器上,或者只是偶尔需要交换一次数据文件交换 是最简单可靠的方案。
  • 如果你正在构建一个大型、分布式的系统,需要将 MATLAB 的计算能力作为一种标准服务提供给多个应用,那么可以考虑 Web 服务 架构。
分享:
扫描分享到社交APP
上一篇
下一篇