MATLAB and Python each have their advantages. MATLAB is strong in matrix operations, and its strengths include Japanese documents and the existence of Simlinks. On the other hand, Python is free to use, and rich machine learning libraries such as scikit-learn are attractive. Therefore, you may want to use these properly.
For such cases, there is Ability to call Python directly from MATLAB. (Conversely, Call MATLAB function from Python is also possible, but I will not touch it this time.)
However, even if I look it up, the official document is not very practical [^ example]. Therefore, this time, I will organize and summarize ** information that seems to be useful in practical use **.
In the past, there were times when I wanted to process the machine learning part in Python and use MATLAB to prepare training data and evaluate the model. You could write and execute the code in each language and exchange the results in a dat file or mat file, but it was a little troublesome. So, when I learned about this function, I thought, "I can make it easier!" (Actually, the conclusion I looked up was "** Python calls from MATLAB are not desirable **")
[^ example]: There is only an example of textwrap.wrap, and I have no idea how to actually use numpy etc ... (I think I wanted to explain it only with the standard library)
Before using it in MATLAB, you need to install the Python interpreter and register its path. However, since python has Official version and Anaconda version, the procedure changes a little. I will.
To use the official version of Python.org, install according to Explanation here. only.
On the other hand, if you do not pass the path in the Anaconda environment or the official version, you need to set the path individually on MATLAB.
First, find out the path of the interpreter you want to use.
Then, set the path checked by pyversion
function.
For example, to use Anaconda's hogehoge
environment, write as follows.
executable = [getenv('userprofile'),...
'\AppData\Local\Continuum\anaconda3\envs\hogehoge\python.exe'];
pyversion(executable);
clearvars executable;
Run pyversion
with no arguments to see if it's set up properly.
If the version is displayed, it should be okay.
Next, let's call a Python function.
To call a function named command
in Python from MATLAB, just use py.command
.
For example, if you want to execute the print function of python, do as follows.
py.print("Hello world!");
However, it should be noted that MATLAB and Python have different built-in data types and grammars. For example, even if it is possible in Python, the following notation is not allowed.
py.print("{0} {1}".format("Hello", "world!"));
% py.print("{0} {1}".format("Hello", "world!"));
% ↑
%error:Unexpected MATLAB operator.
For proper execution, [explicitly convert MATLAB String type to Python string type](https://jp.mathworks.com/help/matlab/matlab_external/handling-data-returned-from- python.html) You need to do it.
py.print(py.str("{0} {1}").format("Hello", "world!"));
Next is about How to import Python packages.
The above page describes the syntax equivalent to from x import y
in python.
However, in practice, syntax like ʻimport numpy as np` is often used.
This can be written as follows from Implementation of import statement on the python side.
%Code equivalent to import numpy as np in Python
np = py.importlib.import_module('numpy');
Data type conversion occurs when exchanging data between MATLAB and Python. The automatic conversions are MATLAB to Python, [Python to MATLAB](https: // It is organized in jp.mathworks.com/help/matlab/matlab_external/handling-data-returned-from-python.html#buialof-53). Here, when passing a 1-by-N vector to Python, it is automatically converted to the built-in array type. However, the M-by-N matrix does not seem to be converted automatically.
matrix = np.array(rand(2));
%error: py.builtin_function_or_method/subsref
% MATLAB 'double'Conversion to Python is 1-Only supported for N vectors.
Therefore, using the fact that Matlab's cell array is automatically converted to Python tuples, it seems that it can be converted to ndarray form by doing the following.
mat_org = rand(2);
for i = 1:size(mat_org, 1)
mat_cell{i} = mat_org(i, :);
end
matrix = np.array(mat_cell);
disp(mat_org); %Original matrix(MATLAB)
py.print(matrix); %Matrix after conversion(ndarray)
It is troublesome to write a for statement every time, so it is better to use it as a function.
mat2ndarray.m
function ndarray = mat2ndarray(mat)
% ndarray = mat2ndarray(mat)Convert matrix to python ndarray format and return
validateattributes(mat, {'numeric'}, {'2d'})
n_rows = size(mat, 1);
mat_cell = cell([1, n_rows]);
for r = 1:n_rows
mat_cell{r} = mat(r, :);
end
ndarray = py.numpy.array(mat_cell);
end
In python, Specify the parameter name and pass it to the function may occur. In this case, the problem is that MATLAB and Python have different grammars. As a solution, use MATLAB's pyargs function.
For example, to find the average for each column of a matrix with numpy, do as follows.
mat = mat2ndarray(rand(2));
%Np in python.average(a=mat, axix=0)Equivalent to
ave = np.average(pyargs('a', mat, 'axis', py.int(0)));
It should be noted here that MATLAB basically treats numbers as double type.
When the processing in Python is finished, you will return to the basic type of MATLAB and plot it. In that case, it is necessary to convert to a MATLAB matrix, but it cannot be simply converted as shown below.
n_mat = np.average(pyargs('a', mat2ndarray(rand(2)), 'axis', py.int(0))); %Some processing result
double(n_mat); %I want to convert to a matlab matrix
%error: double
% py.numpy.Unable to convert from ndarray to double.
Therefore, it needs to be converted as well as [How to pass a matrix](# How to pass a matrix (MATLAB to ndarray)).
Therefore, once converted to a vector of type ʻarray.array, use the information of
ndarray.shape` to [reshape function](https://jp.mathworks.com/help/matlab/ref/reshape. Shape it with html).
Specifically, it can be converted with the following function [^ refdiscussion].
function mat = ndarray2mat(ndarray)
% mat = narray2mat(mat)Converts python narray format matrix to MATLAB format matrix and returns
validateattributes(ndarray, {'py.numpy.ndarray'}, {'scalar'});
np = py.importlib.import_module('numpy');
shape = cell(ndarray.shape); %Read the shape
shape = cellfun(@(x) int64(x), shape); % py.Convert int to int64
if shape == 1
%For scalars, prevent errors
shape = [1, 1];
end
%Read data as vector
data = py.array.array(ndarray.dtype.char, np.nditer(ndarray));
data = double(data); % py.array.Convert array to double
mat = reshape(data, shape); %Arrange the shape in a matrix
end
[^ refdiscussion]: I referred to this discussion.
Let's display the result with matplotlib without relying on the MATLAB plotting tool [^ matplotlib]. However, in my environment (Anaconda), a Qt-related error occurred and I could not plot.
So, I added environment variables by referring to this article, and I was able to plot well. Below is the code to add the Qt path for the hogehoge environment.
QtPath = [getenv('userprofile'),...
'\AppData\Local\Continuum\anaconda3\envs\hogehoge\Library\plugins'];
setenv('QT_PLUGIN_PATH', [getenv('QT_PLUGIN_PATH'), QtPath]);
clearvars QtPath;
If I put this code in startup.m
, I could plot it properly.
[^ matplotlib]: It is strange to use matplotlib, which provides MATLAB-like graph drawing, on MATLAB ...
However, I feel that matplotlib is better for the default color scheme.
If you use Python, you want to use scikit-learn or seaborn. However, it seems that these cannot be imported for some reason.
%I can't even see the help ...
py.help('seaborn')
% problem in seaborn - ImportError: DLL load failed:The specified procedure cannot be found.
If anyone knows the cause or solution, please let me know ...
The above is the method of using Python from MATLAB in the range I investigated. In conclusion, I thought it would be overwhelmingly easier to execute ** individually and hand over the files **. I think it's many times easier to write a process to pass a csv file using a library than to learn how to call Python from MATLAB.
<!-Also, if you set the process to transfer files, transfer to other languages will be smooth. ->
Also, in my environment, it is fatal that ** scikit-learn cannot be used **. If it's just the numpy and scipy features, I think the MATLAB built-in functions are more powerful.
In addition, spyder and pycharm provide support such as powerful code completion, but MATLAB provides poor support.
Considering the above, the current "Python call from MATLAB" is not a very good method. However, there are some parts that have not been fully investigated, so if you are familiar with it, I would appreciate it if you could supplement it with comments.
As an alternative, it is better to prepare MATLAB script and Python script respectively, and exchange data by file or standard input / output. For example, if you have a main MATLAB script (main.m) and a Python script (hogehoge.py) that performs processing, the processing will be as follows.
! Python hogehoge.py
Recommended Posts