loading from *.mat file directly into a structure
246 views (last 30 days)
Show older comments
OK, I'm taking your suggestions to heart...eliminate the "eval"s and "poofing" variables into my workspace in my code. But I have a question:
Each wkrspc is saved to its own *.mat file with a single variable (a 6x6 cell array) with the structure shown above. If I want to replace the code:
load([wrkspcs{iwrk},'.mat']) %creates variables in workspace matching the file name
(which "poofs" the variable 'ZLH_151212_WrkSpc' into the workspace) with the preferred "load into structure" replacement statement
>> tmp=load([wrkspcs{1},'.mat'])
tmp =
struct with fields:
ZLH_151212_WrkSpc: {6×6 cell}
it works fine. I can then copy the cell array from the 'tmp' struct to myStruct
>> myStruct.(wrkspcs{1})=tmp.(wrkspcs{1})
myStruct =
struct with fields:
ZLH_151210_WrkSpc: {6×6 cell}
But how can I do the load directly into 'myStruct' struct? When I try:
>> myStruct.(wrkspcs{1})=load([wrkspcs{1},'.mat'])
myStruct =
struct with fields:
ZLH_151210_WrkSpc: [1×1 struct]
>> myStruct.ZLH_151210_WrkSpc
ans =
struct with fields:
ZLH_151210_WrkSpc: {6×6 cell}
>> myStruct.ZLH_151210_WrkSpc.ZLH_151210_WrkSpc
ans =
6×6 cell array
{1×1 struct} {[1]} {'16557'} {'1210'} {'zlh_1a'} {'ZLH_151210'}
{1×1 struct} {[1]} {'16676'} {'1210'} {'zlh_1b'} {'ZLH_151210'}
{1×1 struct} {[2]} {'16557'} {'1213'} {'zlh_2a'} {'ZLH_151210'}
{1×1 struct} {[2]} {'16676'} {'1213'} {'zlh_2b'} {'ZLH_151210'}
{1×1 struct} {[3]} {'16557'} {'1216'} {'zlh_3a'} {'ZLH_151210'}
{1×1 struct} {[3]} {'16676'} {'1216'} {'zlh_3b'} {'ZLH_151210'}
and my 6x6 cell array gets buried 2 levels deep in 'myStruct'. Now I have no idea how to directly get the 6x6 cell array to be "loaded" directly as the first level field in 'myStruct' -- same as the result I get when going through a 'tmp' struct as shown above. Specifying the variable name in the 'load' statement makes no difference. Also, specifying the 'myStruct' field directly in the load statement makes no difference.
Now I did read the "load()" documentation pretty carefully and it does suggest the result of the "s = load()" will always be a structure, so I guess my observed behavior is correct -- but it seems like there should be a way to avoid the "struct.struct.value" result when the LHS of the assignment is already a structure.
Again, I need some help understanding this behavior and any workaround to avoid going thru loading to a temporary structure and copying the desired field to my structure variable.
2 Comments
Rik
on 8 May 2018
What would be the problem of doing this and then removing one layer with your_struct=your_struct.your_struct;?
Accepted Answer
Stephen23
on 8 May 2018
Edited: Stephen23
on 8 May 2018
Copied from https://www.mathworks.com/matlabcentral/answers/398961-advise-on-accessing-cell-array-containing-structures:
"But how can I do the load directly into 'myStruct' struct?"
You can't. Not in the way that you are trying to do it, without a temporary variable. load returns a scalar structure and you will have to allocate that to a temporary variable and then access its fields, as Ameer Hamza already explained. This is quite efficient and does not waste memory, so there is no reason to avoid it.
"...any workaround to avoid going thru loading to a temporary structure..."
as Ameer Hamza wrote, MATLAB does not allow arbitrary indexing/fieldname access to be suffixed onto function calls, so it is quite normal in MATLAB to allocate data to a temporary variable before doing some simple indexing, or accessing fields. This is standard MATLAB practice, wastes no memory whatsoever, and you have not explained why you need to avoid it.
Alternative 1: using a non-scalar structure has advantages also, when you try to process/access the data. You might like to consider doing something like this:
tmp = load([wrkspcs{k},'.mat']);
myStruct(k).data = tmp.(wrkspcs{1});
myStruct(k).name = wrkspcs{k};
The trick is to think of meta-data as data in their own right. Storing data in this way will make your code much simpler, more robust, and more generalized, which means that you can spend more time on actually processing your data rather than worrying about fieldnames and variable names and mat files and ...
Alternative 2: if each .mat file contains exactly one field/variable, then there is no real advantage to using a structure anyway, and you could easily use a cell array for all of your data. If the fields are the same size then it could even be a 3D array and then there would be no nesting of cell arrays:
out = cell(6,6,numel(wrkspcs));
for k = 1:numel(wrkspcs)
tmp = load([wrkspcs{k},'.mat']);
out(:,:,k) = tmp.([wrkspcs{k})
end
Alternative 3: Note that most of the complication here come from bad data design anyway: contrary to what some beginners think, it is much easier to process data when the variable names do not change (yes, even the ones inside .mat files). If each .mat file simply had the exactly same variables, e.g. data and name, then you really could import the files in exactly the way that you requested, without any temporary variable:
for k = numel(wrkspcs{k}):-1:1
S(k) = load([wrkspcs{k},'.mat']);
end
and you would get one non-scalar structure containing all of your data, without any nesting:
S(1).data
S(1).name
or all of the names in a cell array:
{S.name}
etc
2 Comments
Stephen23
on 13 May 2018
Edited: Stephen23
on 13 May 2018
Re "wasting no memory": MATLAB uses a form of memory management that is called "copy on write", which basically means that as long as an array is not changed (e.g. values or size) then it can have different handles (e.g. variable names) and even be passed between function workspaces without actually being copied in memory. So when you import that data and allocate one of the fields to a temporary variable then the data array itself is (probably) not copied. Read more here:
You might like to read some of the discussions on this topic:
Of course what really happens is a bit more complex than that, but that is the gist of it. Disclaimer: I don't work for TMW, the exact implementation of the memory management is not documented, and it can change between versions...
More Answers (0)
See Also
Categories
Find more on Structures in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!