我需要从MATLAB调用一个Python函数,我该怎么做?
我需要从MATLAB调用一个Python函数,我该怎么做?
我在我的系统上有一个类似的要求,这是我的解决方案:
在MATLAB中有一个叫做perl.m的函数,它允许你从MATLAB中调用perl脚本。根据你所使用的版本,它可能会被放置在某个位置。
C:\Program Files\MATLAB\R2008a\toolbox\matlab\general\perl.m
创建一个名为python.m的副本,快速查找并替换perl为python,仔细检查设置的命令路径是否指向您安装的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
>>
fullfile(matlabroot, 'sys\python\win32\bin\');
指向的路径实际上并不存在,因为没有定义任何Python错误消息,所以在CTRL+F'd Perl.m中使用message('MATLAB:python:<>')
错误消息是无效的。 - jrhpy
前缀也可以用于用户定义的 Python 模块(脚本):例如 names = py.mymod.search(N)
。正确的文档页面是:https://uk.mathworks.com/help/matlab/matlab_external/call-user-defined-custom-module.html。 - Kouichi C. Nakamura尝试使用这个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);
正如 @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
之前。
numpy.ndarray
被用作 MATLAB N-D 矩阵的等效物)和 MATLAB 类型之间来回转换(实际上,在 MEX 中,使用的是 mxArray
)。 - Amro因此,基本上你可以像在命令提示符(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在当前目录中查找使用system
命令指定的Python文件。
这可能是解决你的问题最简单的方法,因为你只需在MATLAB中使用现有函数即可完成你的任务。
从Matlab 2014b开始,可以直接调用Python函数。 使用前缀py,然后是模块名称,最后是函数名称,如下所示:
result = py.module_name.function_name(parameter1);
如果你在与Python脚本不同的工作目录中,从Matlab调用Python脚本时,请确保将脚本添加到Python搜索路径中。
更多详细信息请参见此处。
perl.m
适配成python.m
,并附上参考资料供其他人使用,但我似乎无法从Python脚本中获取任何输出并返回给MATLAB变量 :(
这是我的M文件;请注意,我在代码中直接指向Python文件夹C:\python27_64
,这在您的系统中可能会有所不同。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指向MATLAB文件夹中的Perl安装程序,通过更新PATH并调用Perl来解决。上面的函数指向我的Python安装程序。当我调用我的function.py
文件时,它在不同的目录中,并调用该目录中的其他文件。这些文件没有反映在PATH中,因此我必须将我的Python文件easy_install到我的Python发行版中。
getenv('SHELL')
。无论如何,你应该提到这个技巧不幸只适用于Linux/Mac。 - Amro