Matlab: Iterating over large groups of stored data - matlab

I am looking at storing my multiple variables into the one array or cell matrix.
The data I currently have is
seaLevel <339x1 double>
tideLevel <201x1 double>
height <55x1 double>
I want to have all of these in the one class so I can iterate through each group.
So varGroup will contain all three of the above variables with their name
Hope someone can help

Just define structure in matlab such as
z = struct('seaLevel', zeros(1,339),
'tideLevel', zeros(1,201),
'height', zeros(1,55));
And you can create an array of structure as well
data(n) = z;

To expand on the other answer and your comments, you can use a struct and still be able to access all of them within a loop by utilizing fieldnames and dynamic field references. Depending on what you're doing with the variables, structfun might also be an option.
For example:
% Dummy data!
seaLevel = rand(339, 1);
tideLevel = rand(201, 1);
height = rand(55, 1);
% Generate our data structure
mydata_struct = struct( ...
'seaLevel', seaLevel, ...
'tideLevel', tideLevel, ...
'height', height ...
);
datafields = fieldnames(mydata_struct);
nvariables = length(datafields);
for ii = 1:nvariables
fprintf('Looping over ''%s'' data, %u data entries\n', datafields{ii}, length(mydata_struct.(datafields{ii})))
end
Which prints the following to the console:
Looping over 'seaLevel' data, 339 data entries
Looping over 'tideLevel' data, 201 data entries
Looping over 'height' data, 55 data entries
As you can see, you can loop over all of your data with a simple loop.
Alternatively, you can utilize a cell array:
% Dummy data!
seaLevel = rand(339, 1);
tideLevel = rand(201, 1);
height = rand(55, 1);
% Generate a cell array
mydata_cell = {seaLevel, tideLevel, height};
nvariables = length(mydata_cell);
for ii = 1:nvariables
fprintf('Looping over data column %u, %u data entries\n', ii, length(mydata_cell{ii}))
end
Which prints the following to the console:
Looping over data column 1, 339 data entries
Looping over data column 2, 201 data entries
Looping over data column 3, 55 data entries
A cell array is slightly simpler, though you lose the ability to reference your data by name like you can with the struct array above. Both approaches allow you to store and access dissimilar data in the same array.

Related

Extract structures in a loop

I have a structure ('data'), with 26 fields (A, B, C, D, etc.). Each field contains 1x30 cells (one for each participant), and each cell contains a structure.
I would like to extract all the structures (i.e., one structure per field) corresponding to each participant. That is, I would like to obtain 30 new ‘data’, each with 26 fields, and each field containing 1x1 structure, with the structure corresponding to the participant. I have tried the following code:
data = load('D:\filepath\mydata.mat'); %load file with data. 1x1 struct.
all_fields = fieldnames(data); %store the fields of the structure. 26x1 cell.
forStr = length(all_fields); %26
n_ppts = 30; %total number of participants.
%for each participant, extract the corresponding structure in each field.
for nn = 1:n_ppts
for idx_field = 1:forStr
name_field = all_fields{idx_field};
data2 = data;
data2.(name_field) = data.(name_field){nn};
end
%save the 'data' for each participant. The 'data' should include 26 fields, and 1 structure for each field.
name = ppt_fname(nn); %Generate the new name for saving
savename =string(regexprep(name,'_oldname.set','_newname.mat'));
save(savename, '-struct', 'data');
end
The code doesn’t give any error. However, it doesn’t run as I expected.
‘data2’ still contains 26 fields, but only the last field contains 1 structure corresponding to the participant. The other fields contain 1x30 cell.
I guess it is because every time I run the loop it overwrites the previous fields, leaving only the last field correct. So, I think I might need a temporary variable where to store each iteration of the loop.
I thought to create as the temporary storage for each field
structure = [];
namelist = {‘A’;’B’;’C’;’D’;’E’;’F’;’G’;’H’;’I’;’J’;’K’;’L’;’M’;’N’;’O’;’P’;’Q’;’R’;’S’;’T’;’U’;’V’;’W’;’X’;’Y’;’Z’};
for i = 1:length(namelist)
structure.(namelist{i})={};
end
But cannot figure out how to make it work.
You need to take the line data2 = data; out of the for loops.
Antoine T is right, you always copy the original structure data again to data2 in every loop. That is why it won't get changed (except for the very last step of the loop, where you add a single field name to it.)
Regarding your other problem:
% create empty struct:
S = struct();
% loop
for i = 1:25
% create field name
nm = char( double('A') +i );
% create new field with empty cell.
S.(nm) = {};
end
It is just nice to convert number to chars as fieldnames. Your primary error was that you used the wrong inverted comma to create chars.
A minor flaw though was that you allocated strucutre = [] as an empty matrix rather than as an empty struct

Storing image data as a row vector

I have multiple images in a folder, and for each image, I want to store the data(pixel values) as a row vector. After I store them in a row vector I can combine these row vectors as one multi dimensional array. e.g. the data for the first image will be stored in row 1, the data for the second image will be stored in row 2 and so on. And any time I want to access a particular image data, let us say I want the third image, I can do something like this race(3,:).
I am currently getting the error:
Dimensions of matrices being concatenated are not consistent.
The error occurs here race = [race; imagevec] I am lost in how to correct this, unless imagevec = I(:)' is not converting the matrix to a row vector .
race = []; % to store all row vector
imagevec = []; % to store row vector
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir('C:\Users\User_\somedir\*.jpg'); % image file extension in directory
for i = 1 : length(path)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
imagevec = I(:)'; % convert image data to row vector
race = [race; imagevec]; % store row vector in matrix
end
Using a cell array instead of a matrix will allow you to index in this way even if your images are of different sizes.
You don't even have to turn them into a row vector to store them all in the same structure. You can do something like this:
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir([path,*.jpg']); % image file extension in directory
race = cell(length(pathfile),1);
for i = 1 : length(pathfile)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
race{i} = I; % store in cell array
end
Then when you want to perform some operation, you can simply index into the cell array. You could even turn it into a row vector, if you wanted to, as follows.
thisImage = race{3}(:)';
If you are using a matrix to store the results, all rows of a matrix must be the same length.
Cell arrays are similar to arrays except the elements need not be the same type / size.
You can accomplish what you are looking for using a cell array. First, initialize race to:
race = {};
Then try:
race = {race{:}, imagevec};

Dividing a DataArray and putting names to each Matlab

I have a data array with dimensions 1 x 95125. I want to extract data from it and then give each a name. For example
Station00001=[R{:,1:13}]
Station00002=[R{:,15:27}]
.....
Station06518
The question is, is it possible to create a vector with all the wanted names and then open each data from the data array as above but with all the files with a for loop to its corresponding file
This is what I did but its not working
for i= 1:(length(R)/14)
k=0:((length(R)/14)-1)
A(i)=1+14.*k;
B(i)=A+12;
Stations (i)= [R{:,A(i):B(i)}];
end
Your loop is fine; not sure why you would want to store the A and B indices in an array, though.
numStations = floor(length(R)/14); %# careful: the number of columns in R is not a multiple of 14
Stations = cell(1,numStations);
for i= 1:numStations
fromColumn = (i-1)*14+1;
toColumn = i*14-1;
Stations{i}= [R{:,fromColumn:toColumn}];
end
To access the data from Station 25, use Stations{25}

How to get all data from a struct?

I've got a result from a web service and MatLab gladly notifies that it is a 1x1 struct. However, when I try to display it (by typing receivedData and pressing enter) I get to see this:
ResponseData: [5x1 struct]
Equally gladly, I entered the following, in my attempt to get the data viewed to me:
struct2array(responseData)
I get only a bunch (not five, more than five) of strings that might be names headers of columns of the data provided.
How do I get all the data from such structure?
You may use fieldnames to get the data from the struct and then iteratively display the data using getfield function. For example:
structvariable = struct('a',123,'b',456,'c',789);
dataout = zeros(1,length(structvariable)) % Preallocating data for structure
field = fieldnames(a);
for i = 1:length(structvariable)
getfield(structvariable,field{i})
end
Remember, getfield gives data in form of cell, not matrix.
or you can use cellfun function:
% STRUCT - your structure
% tmp_nam - structure field names
% tmp_val - values for structure field names
tmp_nam = fieldnames(STRUCT);
tmp_val = cellfun(#(x)(STRUCT.(x)),tmp_nam,'UniformOutput',false);
In order to display all elements and subelements of a structure there is a custom function that you can download here:
http://www.mathworks.com/matlabcentral/fileexchange/13831-structure-display
Some useful access syntax:
someVar = ResponseData(1) %Displays the first element
someVar = ResponseData(4) %Displays the 4th element
To display them all, one after the next
for ix = 1:length(ResponseData)
tmp = ResponseData(ix);
end
To get all the fieldnames
names = fieldnames(ResponseData)
To get all 5 data elements from the structure with the first field names, and put them into a cell array
ixFieldName = 1;
someCellArray = { ResponseData.(ixFieldName{1}) }
A small correction to Sahinsu's answer:
structvariable = struct('a',123,'b',456,'c',789);
dataout = zeros(1,length(structvariable)) % Preallocating data for structure
field = fieldnames(structvariable);
for i = 1:length(field)
getfield(structvariable,field{i})
end

Create an array of 'Geostruct' Data in Matlab

Right now I am creating mapstructs in Matlab and then exporting them individually as shape files using the shapewrite() function.
However, instead of exporting them individually I want to store all of them into an array and then save it at the end as one single shapefile which holds all of the points from the mapstructs stored in the array.
My problem is I don't know how to initialize an array to hold these mapstructs. I've tried
`a = struct(sizeofarray)`
but it isn't compatible with mapstructs. I would appreciate any help!
You can store any kind of data in a cell array:
a = cell(sizeofarray,1);
You can then assign them like this:
a{1} = firstmapstruct;
a{2} = secondmapstruct;
However, if I understand you correctly you have mapstructs from the MATLAB Mapping Toolbox and want to concat structs of this form:
firstmapstruct =
609x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTH
So you should probably do
a = firstmapstruct;
a(end+1:end+numel(secondmapstruct))= secondmapstruct;
and so on...
If all of your individual mapstructs have the same fields, you should be able to initialize a structure array by replicating one of your mapstructs using the function REPMAT:
a = repmat(mapstruct1,1,N); %# A 1-by-N structure array
Then just fill in each element as needed:
a(2) = mapstruct2; %# Assign another mapstruct to the second array element
a(3).X = ...; %# Assign a value to the X field of the third element
a(3).Y = ...; %# Assign a value to the Y field of the third element
You can find out more information about Geographic Data Structures in this documentation.