Convert Python tuple output into MATLAB array

49 次查看(过去 30 天)
Hello everyone,
I am facing a simple problem, probably due to the fact that I have not been using python for a long time.
Simply put, I wrote a function OPUSImport with Python which opens a particular file (infrared spectra from a specific company) from its FilePath. The function that allows to read this particular file read_file is available only from a Python module, brukeropusreader.
def OPUSImport(FilePath):
from brukeropusreader import read_file
OPUSData = read_file(FilePath)
WaveNum = OPUSData.get_range("AB")
Abs = OPUSData["AB"][0:len(WaveNum)]
return WaveNum, Abs
As you can see from the function, read_file produces a Python object OPUSData and passes as output the wavenumber WaveNum (X axis) and the infrared absorbance values Abs (Y axis).
The main problem is that I would like to use this Python function into a MATLAB one:
function Files = OPUSImport(FolderPath)
Files = dir(FolderPath);
PopLogic = true(size(Files));
for i = 1:size(Files, 1)
if contains(Files(i).name, ".0") % file has the correct extension
PyOutput = py.pyOPUS.OPUSImport(FolderPath + string(Files(i).name)); % read file with the Python function, saved in the module pyOPUS
Files(i).data.Blocks.XData = double(PyOutput(1));
Files(i).data.Blocks.YData = double(PyOutput(2));
else
PopLogic(i) = false;
end
end
Files = Files(PopLogic); % keep only structure entries with valuable data
end
The function iteratively scans through all the data files in a folder, opens and reads the correct ones (".0"). The system works up to PyOutput, which is a tuple. The issue is that the double() function from MATLAB does not convert the tuple into a double array, with the following error:
Error using py.tuple/double
Python list/tuple element at position 1 must be type
'double'.
Indeed PyOutput is a 1x2 tuple and has the following content:
val =
(array([7499.95803452, 7499.92790235, 7499.89777018, ..., 370.05469869,
370.02456652, 369.99443436]), array([0.01676818, 0.01727641, 0.01768954, ..., 0.0493812 , 0.04995102,
0. ]))
Use string, double or cell function to convert to a MATLAB array.
Is there a better way to pass the output tuple to matlab?
Thank you in advance for the answer.

采纳的回答

Stephen23
Stephen23 2024-11-13,8:46
编辑:Stephen23 2024-11-13,9:15
"The issue is that the double() function from MATLAB does not convert the tuple into a double array"
No, the issue is actually that your TUPLE contains non-scalar arrays (which are LISTs i.e. container arrays, not numeric). So rather than calling DOUBLE it would make a lot more sense to call CELL. In fact, that is exactly what MATLAB advises, when you read the message it shows (you can also read this message in your question):
T = pyrun("x = ([1,2],[98,99])","x")
T =
Python tuple with values: ([1, 2], [98, 99]) Use string, double or cell function to convert to a MATLAB array.
DOUBLE requires that every TUPLE element is a numeric (probably scalar, but I did not check this), which your data are not (ultimately they are LISTs, not numeric):
try
double(T)
catch ME
ME.message
end
ans = 'Python list/tuple element at position 1 must be type 'double'.'
Solution One
Lets try CELL instead (which in general makes much more sense for a container array like TUPLE anyway):
C = cell(T)
C = 1x2 cell array
{1x2 py.list} {1x2 py.list}
Converting the nested LISTs is then very easy:
C = cellfun(@double,C,'uni',0)
C = 1x2 cell array
{[1 2]} {[98 99]}
This is also explained in the MATLAB documentation:
Or more generally:
Solution Two
Another approach is to simply use the correct indexing for accessing the content of a container array (i.e. curly braces), much like what you attempted in your question (except you used parentheses, which just like every other indexing operation using parentheses returns the array itself, not its content):
V1 = double(T{1})
V1 = 1×2
1 2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
V2 = double(T{2})
V2 = 1×2
98 99
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Indexing into Python container types is explained in the MATLAB documentation:
Or more generally:

更多回答(1 个)

Divyajyoti Nayak
Divyajyoti Nayak 2024-11-12,18:28
I see that you want a way to pass arrays in a python tuple and use them in MATLAB. The python tuple can be passed into MATLAB in a '.mat' file using the 'savemat' function from the 'SciPy' module. The '.mat' file can then be loaded into MATLAB and used as the desired MATLAB data type. Al Danial's answer in this MATLAB Answers question can help you out:
Hope this helps!
  1 个评论
Francesco
Francesco 2024-11-13,7:36
thank you very much for your answer. Passing the information through a .mat file could be a viable option and I onestly thought about it, but I find hard to believe that there is not a better in-code way to do it. Moreover, in case of lots of data, the iterative write-read operation is time-consuming. I will implement your suggestion for now. Thank you very much!

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Call Python from MATLAB 的更多信息

产品


版本

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by