从MATLAB调用Python函数


72

我需要从MATLAB调用Python函数。我怎样才能做到这一点?


2
MATLAB是否支持套接字?
地理

1
显然,如果确实有帮助,它确实具有套接字支持code.google.com/p/msocket
Adrian

如果我们要添加选项:github.com/kw/pymex
robince 2013年

与将Matlab代码转换成Python(也提到了一些调用接口)相反的方向:stackoverflow.com/q/9845292/1959808
Ioannis Filippidis

为什么不接受答案?提出问题时,“正确”的答案不存在,但现在已经存在:stackoverflow.com/a/29189167/1959808
Ioannis Filippidis

Answers:


47

我对系统有类似的要求,这是我的解决方案:

在MATLAB中,有一个名为perl.m的函数,该函数可让您从MATLAB中调用perl脚本。根据您使用的版本,它会位于类似

C:\Program Files\MATLAB\R2008a\toolbox\matlab\general\perl.m

创建一个名为python.m的副本,快速搜索并用python替换perl,仔细检查其设置的命令路径以指向您的python安装。您现在应该可以从MATLAB运行python脚本。

python中一个简单的平方函数,另存为“ sqd.py”,如果正确执行此操作,自然会在测试输入参数,有效数字等方面进行一些检查。

import sys

def squared(x):
    y = x * x
    return y

if __name__ == '__main__':
    x = float(sys.argv[1])
    sys.stdout.write(str(squared(x)))

然后在MATLAB中

>> r=python('sqd.py','3.5')
r =
12.25
>> r=python('sqd.py','5')
r =
25.0
>>

2
perl只是进行系统调用以执行Perl脚本-在Perl脚本和MATLAB之间没有数据传输,除了“尝试对结果进行Perl调用的结果及其从状态到状态的退出”。- mathworks.com/access/helpdesk/help/techdoc/ref/perl.html
雅各布

我同意这只是进行系统调用,但是如果不需要,为什么要使用mex函数和套接字使事情变得复杂呢?在简单的级别上,对python的调用确实具有简单的数据传输。我将用示例更新答案。
阿德里安

6
+1-MATLAB示例代码看起来很棒-您可以发布(代码/链接)python.m吗?返回的数据有什么限制-仅标量?
雅各布

我们可以将数组也作为参数传递给python文件吗?
Donbeo 2014年

请注意,这行之有效,但这是一个hack,有很多路径并没有真正走到任何地方,例如,fullfile(matlabroot, 'sys\python\win32\bin\');指向的路径实际上并不存在,没有定义任何python错误消息,因此message('MATLAB:python:<>')错误消息赢得了在CTRL + F'd Perl.m中不起作用
jrh

28

使用Matlab 2014b可以直接从matlab调用python库。前缀py.添加到所有数据包名称:

>> wrapped = py.textwrap.wrap("example")

wrapped = 

  Python list with no properties.

    ['example']

5
这确实是一个很酷的功能-但似乎不完整-例如,我不能以这种方式使用sklearn。有关详细信息,请参阅我的问题
巴斯蒂安·埃伯林

py前缀也可以用于用户定义的python模块(脚本):例如。names = py.mymod.search(N)。正确的文档页面是这样的:uk.mathworks.com/help/matlab/matlab_external/...
耕一C.中村

19

尝试使用此MEX文件从MATLAB实际调用Python,而不是像其他人建议的那样。它提供了相当不错的集成:http : //algoholic.eu/matpy/

您可以轻松地执行以下操作:

[X,Y]=meshgrid(-10:0.1:10,-10:0.1:10);
Z=sin(X)+cos(Y);
py_export('X','Y','Z')
stmt = sprintf(['import matplotlib\n' ...
'matplotlib.use(''Qt4Agg'')\n' ...
'import matplotlib.pyplot as plt\n' ...
'from mpl_toolkits.mplot3d import axes3d\n' ...
'f=plt.figure()\n' ...
'ax=f.gca(projection=''3d'')\n' ...
'cset=ax.plot_surface(X,Y,Z)\n' ...
'ax.clabel(cset,fontsize=9,inline=1)\n' ...
'plt.show()']);
py('eval', stmt);

1
+1感谢您提供的出色解决方案。请考虑将项目托管在GitHub上,以便其他人也可以找到它
Amro

2
对于那些感兴趣的人,我刚刚找到了另外两个类似的项目:pythoncallpymex(我自己还没有尝试过)
Amro

14

您可以将Python脚本嵌入C程序中,然后与MATLAB混合C程序,但是与将结果转储到文件相比,这可能需要大量工作。

您可以使用PyMat在Python中调用MATLAB函数。除此之外,SciPy具有几个MATLAB复制功能。

但是,如果您需要从MATLAB运行Python脚本,则可以尝试运行系统命令来运行脚本并将结果存储在文件中,并稍后在MATLAB中读取。


11

正如@dgorissen所说,Jython是最简单的解决方案。

只需从主页安装Jython 。

然后:

javaaddpath('/path-to-your-jython-installation/jython.jar')

import org.python.util.PythonInterpreter;

python = PythonInterpreter; %# takes a long time to load!
python.exec('import some_module');
python.exec('result = some_module.run_something()');
result = python.get('result');

有关示例,请参阅文档

注意:我从未真正使用过Jython,似乎人们可能从CPython知道的标准库并未在Jython中完全实现!

我测试的一些小示例效果很好,但是您可能会发现必须将Python代码目录添加到sys.path


2
绝对更容易集成。太糟糕了,到目前为止,您无法将Jump和Jump一起使用Numpy / Scipy / matplotlib之类的模块(由于C扩展)。这些库确实是Python在科学计算方面的强项
Amro

很难回答这个问题。也可以只打开Python(在Matlab之外)并在REPL Shell中进行读写操作。我猜想只有Jython才能实现无缝集成。然后再次使用ctypes可能很容易将Octave(而不是Matlab)集成到CPython中。
2012年

(当然,Octave是Matlab的微不足道的替代品。)
2012年

CPython允许其解释器嵌入C程序中(这是@algoholic使用MEX文件完成的工作)。大部分代码都涉及在Python类型(numpy.ndarray等同于MATLAB ND矩阵)和MATLAB类型(确实mxArray在MEX中)之间来回转换。
Amro 2012年

1
整个过程与您上面显示的类似,仅使用Python的C API而不是Jython Java API来评估解释器中的任意表达式...另外,您可以导入任何已安装的Python模块,包括整个PyLab集成
Amro

9

最简单的方法是使用MATLAB系统功能。

因此,基本上,您将像在命令提示符(Windows)或shell(Linux)上一样在MATLAB上执行Python函数:

system('python pythonfile.py')

上面仅用于运行Python文件。如果您想运行Python函数(并为其提供一些参数),那么您将需要:

system('python pythonfile.py argument')

举一个具体的例子,请在Adrian对此问题的解答中使用Python代码,并将其保存到Python文件中,即test.py。然后将此文件放在您的MATLAB目录中,并在MATLAB上运行以下命令:

system('python test.py 2')

您将得到4或2 ^ 2的输出。

注意:MATLAB在当前MATLAB目录中查找您使用system命令指定的任何Python文件。

这可能是解决问题的最简单方法,因为您只需使用MATLAB中的现有函数进行出价即可。


这是我一直在做的,但是我遇到了一个神秘的问题-我的python脚本的参数之一是一个文件。从MATLAB调用时,python脚本无法找到文件(尽管所有脚本都与该文件位于同一目录中,尽管在MATLAB脚本中指定了完整路径)。疯了
whlteXbread 2012年

这些建议看起来不错,但我收到错误消息“'python'无法识别为内部或外部命令,可操作程序或批处理文件。”
NeStack

6

从Matlab 2014b开始,可以直接调用Python函数。使用前缀py,然后使用模块名称,最后使用函数名称,如下所示:

result = py.module_name.function_name(parameter1);

从Matlab调用时,如果您所在的工作目录与Python脚本不在同一个目录中,请确保将脚本添加到Python搜索路径中。

在这里查看更多详细信息。


4

我已经调整了perl.mtopython.m并将其附加给其他人参考,但是我似乎无法从Python脚本中获得任何输出返回给MATLAB变量:(

这是我的M文件;请注意,我直接C:\python27_64在代码中指向Python文件夹,这在您的系统上会更改。

function [result status] = python(varargin)
cmdString = '';
for i = 1:nargin
    thisArg = varargin{i};
    if isempty(thisArg) || ~ischar(thisArg)
        error('MATLAB:python:InputsMustBeStrings', 'All input arguments must be valid strings.');
    end
    if i==1
        if exist(thisArg, 'file')==2
            if isempty(dir(thisArg))
                thisArg = which(thisArg);
            end
        else
            error('MATLAB:python:FileNotFound', 'Unable to find Python file: %s', thisArg);
        end
    end
  if any(thisArg == ' ')
    thisArg = ['"', thisArg, '"'];
  end
  cmdString = [cmdString, ' ', thisArg];
end
errTxtNoPython = 'Unable to find Python executable.';
if isempty(cmdString)
  error('MATLAB:python:NoPythonCommand', 'No python command specified');
elseif ispc
  pythonCmd = 'C:\python27_64';
  cmdString = ['python' cmdString];  
  pythonCmd = ['set PATH=',pythonCmd, ';%PATH%&' cmdString];
  [status, result] = dos(pythonCmd)
else
  [status ignore] = unix('which python'); %#ok
  if (status == 0)
    cmdString = ['python', cmdString];
    [status, result] = unix(cmdString);
  else
    error('MATLAB:python:NoExecutable', errTxtNoPython);
  end
end
if nargout < 2 && status~=0
  error('MATLAB:python:ExecutionError', ...
        'System error: %sCommand executed: %s', result, cmdString);
end

编辑:

解决了我的问题,原始的perl.m通过更新PATH然后调用Perl指向MATLAB文件夹中的Perl安装。上面的功能指向我的Python安装。当我调用文件时,该文件位于另一个目录中,并在该目录中调用了其他文件。这些没有反映在PATH中,我不得不将Python文件easy_install安装到我的Python发行版中。function.py


4

一个鲜为人知的(和小文件)其实关于MATLABsystem()功能:在unixoid系统,它使用任何解释在环境变量被赋予SHELLMATLAB_SHELL在启动MATLAB的时间。因此,如果您以

SHELL='/usr/bin/python' matlab

随后的所有system()调用都将使用Python而不是默认的shell作为解释器。


在Windows上对我不起作用。(我以通常的方式创建了环境变量)
Amro 2013年

嗯,我想您是在Matlab中检查了变量是否已设置好吗?但是如果Matlab在Windows中有不同的标准来决定使用哪个shell,我不会感到惊讶。
quazgar 2013年

是的,我getenv('SHELL')在MATLAB中进行了检查。无论如何,您应该提到它,不幸的是,该技巧仅适用
Amro

1
+1似乎在这里提到了SHELL变量:mathworks.com/help/matlab/ref/matlabunix.html(Windows对应页面,没有)
Amro

3

由于MATLAB与Java无缝集成,因此您可以使用Jython编写脚本并从MATLAB调用它(您可能必须添加一个薄的纯JKava包装器才能实际调用Jython代码)。我从未尝试过,但是我看不出为什么它不起作用。


3

就像Daniel所说的那样,您可以使用py直接从Matlab运行python命令。命令。要运行任何库,只需确保Malab运行安装了库的python环境:

在Mac上:

  • 打开一个新的终端窗口;

  • 类型:哪个python(找出python的默认版本安装在哪里);

  • 重新启动Matlab;

  • 在命令行中键入:pyv​​ersion('/ anaconda2 / bin / python')(显然用您的路径替换)。
  • 现在,您可以在默认的python安装中运行所有库。

例如:

py.sys.version;

py.sklearn.cluster.dbscan


1
这是我在这里找到的最简单的解决方案,应该进一步完善!
NeStack


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.