Proper importing of MATLAB structures into Python

536 ビュー (過去 30 日間)
Milad K
Milad K 2018 年 2 月 19 日
編集済み: Milad K 2018 年 2 月 20 日
I have a MATLAB (2017b) structure which is saved (attached) as lib.mat. This structure, at its highest level, is basically a library with three different fields including an array of structures: ['name', 'structures' [1 x 32 struct], 'structlist', {1 x 32 cell}].
I have tried two different methods to import this structure into Python (v3.5):
a) Import using the io module from Scipy library
import as spio
lib = spio.loadmat('lib.mat')
which produces a dict in python called 'lib' whose fields are not accessible (at least I am not aware how to access, for example, the 32 structures listed in the field 'structures' [1 x 32 struct]).
b) calling MATLAB engine in Python (v3.5) and using getfield function to access different fields of the structure:
import matlab.engine
eng = matlab.engine.start_matlab()
Obj = eng.load('lib.mat')['lib']
Names = eng.getfield(Obj, 'name')
Strs = eng.getfield(Obj, 'structures')
StrLists = eng.getfield(Obj, 'structlist')
where everything works but
Strs = eng.getfield(Obj, 'structures')
is not able to restore the 32 structures in variable Strs. For example if you try:
>>> eng.size(StrLists)
the result would be: matlab.double([[1.0,32.0]]), which is correct, but if you try
>>> eng.size(Strs)
the results is: matlab.double([[0.0,0.0]]), which is incorrect (must be the same size as StrList).
Now my question is how to properly import such data structures into Python and access to their fields.

回答 (1 件)

Bo Li
Bo Li 2018 年 2 月 20 日
Would you share more details about how the file "lib.mat" is created? I tried following steps:
>>lib.Strs = Strs
>>lib.StrList = {1,2,3}
>>save('lib', 'lib')
This what I see in Python:
>>>Obj = eng.load('lib.mat')['lib']
ValueError: only a scalar struct can be returned from MATLAB
This is the expected behavior as Struct array is not supported according to the doc:
In this case, "lib" itself is a scalar struct but the element "Strs" is a struct array.
  1 件のコメント
Milad K
Milad K 2018 年 2 月 20 日
編集済み: Milad K 2018 年 2 月 20 日
Thanks for the reply. To shortly answer your question: lib.mat contains an object created using a GDS-generator library supported by MATLAB.
The way I found to go around this is to first convert this object to an array of structures in MATLAB:
step 1) Make a 1x1 "nested" structure in Matlab
lib2 = struct(lib)
and save it as lib.mat. This conversion from the original object produces a 1x1 structure containing all the fields ['name', 'structures' [1 x 32 struct], 'structlist', {1 x 32 cell}].
Step 2) load the nested structures in Python using
By employing the modified version of, explained in Stackoverflow, the nested structure lib2 saved in lib.mat can be then properly imported as a dictionary into python.


Community Treasure Hunt

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

Start Hunting!

Translated by