【问题标题】:Calling MATLAB .m-files and functions in Python script在 Python 脚本中调用 MATLAB .m 文件和函数
【发布时间】:2012-11-07 14:35:38
【问题描述】:

我有一个python脚本平台,我想在里面调用matlab函数。我发现了几个线程来解决这个问题,其中两个

How do I interact with MATLAB from Python?

Running m-files from Python

但是,线程要么不是最新的,要么不是很详细。

  1. mlabwrap 可靠吗?
  2. 作为在 python 脚本中调用 matlab 函数/.m 文件的解决方案,您会提倡什么?
  3. 使用 python 中的 win32com 调用 matlab 会话 --> 这是个好主意吗?您能否指出更多关于此主题的文档或示例?

似乎指向 sourceForge 的链接不是最新的,最后一次更新是 2010 年,

http://sourceforge.net/projects/mlabwrap/

  1. 你能提示一些最新版本吗?

谢谢

【问题讨论】:

  • mlabwrap虽然有一段时间没有更新了,但是最近有几个非常积极的cmets。因此,我想这个建议仍然有效。
  • @FredrikRedin 什么都没有:我的工作站上没有 matlab。这是一个普遍的问题。
  • 看起来像*.com/questions/2883189/…的部分副本

标签: python matlab interface call mlabwrap


【解决方案1】:

自 MATLAB R2014b 以来,现在有一个用于 Python 的 MATLAB API。有关详细信息,请参阅 MATLAB documentation。但是,它需要启动 MATLAB 引擎,这可能需要一些时间。

【讨论】:

    【解决方案2】:

    回答您的问题:

    1. 我们使用了 mlabwrap,它很可靠。唯一的困难是编译它。我们有一些问题。但是,一旦你编译它,它就会运行良好。
    2. 我会推荐matlab_wrapper,因为它更容易安装(纯Python,无需编译),支持各种数据结构(数字、逻辑、结构、元胞数组)并在GNU/Linux、Windows、OSX上运行。
    3. 使用 win32com 与 MATLAB 进行通信应该可以工作,但它的级别很低且不可移植。

    免责声明:我是 matlab_wrapper 的作者。

    【讨论】:

      【解决方案3】:

      mlabwrapper

      是 python MATLAB 桥接的绝佳解决方案。如果某些事情对您不起作用,只需报告 SO 上的具体问题 :)

      您必须注意,作为项目的 mlabwrapper 已经存在了很长一段时间。 http://mlabwrap.sourceforge.net/

      我最近遇到了 mlabwrap.cpp 的问题,为此我找到了以下 github fork

      相关 这里是 mlabwrap v1.1-pre 的副本 (http://mlabwrap.sourceforge.net/) 按此处所述进行修补: http://sourceforge.net/mailarchive/message.php?msg_id=27312822

      带有修复错误的补丁:

      mlabraw.cpp:225:错误:从“const mwSize*”到的无效转换 ‘const int*’ 另请注意,在 Ubuntu 中,您需要 sudo apt-get install csh

      详情见http://github.com/aweinstein/mlabwrap

      mlab

      花了更多时间后,我做了一个 github 镜像来更新、修复和维护包装器https://github.com/ewiger/mlab(欢迎补丁和拉取请求!)

      可以pip安装,即

      pip install mlab
      

      我暂时排除了 cpp 实现。目前它的工作方式如下:

      对于 Linux/Mac 库创建与 MATLAB 实例的管道连接。剩下的就是序列化(@brentlance 部分指出),这是使用 numpy 完成的。

      对于 Windows 库使用 DCOM 进行通信。 (但我仍然要使用注册表修复版本查找)。

      何时使用 mlab?

      我建议在 MATLAB 中调用非常高级的用户函数(主要返回逻辑结果或非常标准的内置类型作为矩阵),以尽量减少与 MATLAB 的任何通信。这种方法非常适合遗留代码,但可能需要编写一些包装接口来简化函数声明。

      总的来说,代码有点繁琐,是很多人拼凑而成的。核心部分(现在是 ma​​tlabpipema​​tlabcom)似乎做得很好。最终,我不建议将 mlab 用于全面的生产应用程序,除非您愿意花时间测试、错误报告、错误修复和功能请求所有用例。

      【讨论】:

        【解决方案4】:

        我仍然会推荐 mlabwrap 作为解决方案。 我在 Linux 和 Windows 上定期(每周?)使用 mlabwrap,跨越几个不同版本的 Python 和几个不同版本的 Matlab。要回答您的具体问题:

        1. mlabwrap 将可靠地跨平台、Python 和 Matlab 版本执行。然而,它确实有限制,并且当超过这些限制时它会可靠地失败。通常,这些都可以解决。
        2. 有关通过 mlabwrap 调用 Matlab 函数与 Matlab 脚本的更多信息,请参阅我的回答 here。该答案还描述了如何解决 mlabwrap 的主要限制之一,即并非所有 Matlab 对象都可以直接转换为 Python 对象。
        3. 我对使用 win32com 调用 Matlab 一无所知。

        我以我将称之为“Python-primary”风格的方式使用了 mlabwrap,其中大部分使用 Python 进行编程,使用 Matlab 作为特定数学函数的库,这些函数在 scipy/numpy 中不可用,并且在'Matlab-primary' 风格,大部分编程在 Matlab 中,最终结果导入 Python 以供某些外部进程使用。

        对于 Python-primary,要记住的是,并非所有 Matlab 函数都会返回 Python 可读的数据。 mlabwrap 将从这些函数返回一个MLabObjectProxy 对象。当您使用 Matlab 函数创建传递给其他 Matlab 函数以实际处理数据的对象时,通常会发生这些情况。例如,您可以使用数字信号处理工具箱创建一个 Welch 频谱对象,然后您可以使用它来获取数据的功率谱。理论上,您可以将这些 MLabObjectProxies 传递给需要它们的 Matlab 函数。根据我的经验,您来回传递这些内容越多,您就越有可能在 mlabwrap 中找到错误。您可以做的是编写一个简单的 Matlab 包装函数,获取对象、处理数据,然后将适当的输出作为数组返回。

        您还可以通过使用 mlabwrap 中的低级命令来解决 MLabObjectProxies 的问题。例如,如果我有一个 matlab_struct,它是一个带有字段 matlab_struct.label 的结构数组,并且我只想要 Python 端的标签,我可以执行以下操作:

        # place matlab_struct into the Matlab workspace 
        mlab._set('matlab_struct', matlab_struct) 
        # convert the labels into a cell array
        matlab_struct_labels = mlab.eval('{matlab_struct.labels}')
        

        可用的主要低级命令是mlab._set('variable_name', variable)mlab.eval('command string')mlab.get('variable_name')

        如果我在 Matlab 中进行大量繁重的处理,比如在其他地方没有的工具箱或插件中,我将编写我称之为“Matlab-primary”的代码,我会尽量避免通过 mlabwrap 来回传递数据,而不是通过调用 .m 脚本来操作 Matlab 工作区中的变量,将结果输出保存到数据文件中,然后将其导入我的 Python 代码中。

        祝你好运!

        【讨论】:

          最近更新 更多