Loading multiple files and extracting dynamically named variables

13 views (last 30 days)
I have 200+ files named 'xxx_000y.mat' and I am trying to extract the variable which is named by the filename and is a 240x320 array and combine all of these into a 3D array.
I have used eval but was told this was slow and not good to use so I have now changed it by using structures. However, it has become ten times slower and rarely finishes running. I am hoping someone can tell me if I am doing anything wrong please (Note: reasonably new to MATLAB):
i=0;
filename=sprintf('filename%d_*.mat',I);
D=dir(filename);
Image_Org=zeros(240,320,length(D));
for i=1:length(D)
s=load(D(i).name);
fn=fieldnames(s);
Image=s.(fn{1});
Image_Org(:,:,i)=Image;
i=i+1;
end
varname=sprintf('Image_Org_%d',I)
assignin('base',varname,Image_Org)

Answers (1)

Steven Lord
Steven Lord on 22 Aug 2017
i=0;
This is unnecessary since you don't use the variable i before your for loop starts, which will overwrite it ...
filename=sprintf('filename%d_*.mat',I);
unless you intended this to use the variable i here. Note that the variable i is not the same as the variable I; MATLAB is case sensitive. Though using variables whose names differ only by case, unless one of those variables is used in a very limited section of your code, can get confusing for humans even if MATLAB can understand the difference.
D=dir(filename);
Image_Org=zeros(240,320,length(D));
for i=1:length(D)
s=load(D(i).name);
The variable in which you're interested is the one whose name matches the file name? In that case consider calling load with two inputs, the second being the list of variables (in this case, a list of one variable name) in which you're interested. This will avoid the need to load every variable in the file, if they contain many variables.
fn=fieldnames(s);
Image=s.(fn{1});
Image_Org(:,:,i)=Image;
Good up to this point.
i=i+1;
This will change the value of i only for the remainder of the body of this iteration of the for loop. When the next iteration starts, your modification of the loop variable will be overwritten. This is the second item in the Tips section of the documentation page for the for keyword. You can eliminate this line.
end
varname=sprintf('Image_Org_%d',I)
assignin('base',varname,Image_Org)
No. Using eval, evalin, assignin, etc. to create variables is highly discouraged, and in this case it is completely unnecessary. You already have a variable in which you want to store your data and you are already using it: Image_Org.
My suspicion, which you can confirm or refute by profiling your code is that the bottlenecks are the file I/O (the length(D) load calls you make during your loop execution) or perhaps the assignin call (which you should delete.)

Categories

Find more on Variables 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!