Dividing a DataArray and putting names to each Matlab - 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}

Related

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};

Naming Image using index of for loop in each iteration

I am working in MATLAB for my image processing project.
I am using a for loop to generate some kind of image data (size of image varies) with each loop iteration. My problem is how do stop it from overwriting the image in next iteration.
Img(i,j)=data
Ideally I would like it to have
Img_1 = data (for 1st iteration)
Img_2 = data (for 2nd iteration)
Img_3 = data (for 3rd iteration)
and so on...
Is there any way, it can be acheived?
Yes, you can use dynamic field names with structures. I wouldn't recommend using separate variable names because your workspace will become unwieldy. Do something like this:
img_struct = struct(); %// Create empty structure
for ii = 1 : num_iterations
%// Do your processing on data
%...
%...
img_struct.(['Img_' num2str(ii)]) = data; %// After iteration
end
This will create a structure called img_struct where it will have fields that are named Img_1, Img_2, etc. To access a particular data from an iteration... say... iteration 1, do:
data = img_struct.Img_1;
Change the _1 to whatever iteration you choose.
Alternatively, you can use cell arrays... same line of thinking:
%// Create empty cell array
img_cell = cell(num_iterations, 1);
for ii = 1 : num_iterations
%// Do your processing on data
%...
%...
img_cell{ii} = data; %// After iteration
end
Cell arrays are arrays that take on any type per element - or they're non-homogeneous arrays. This means that each element can be whatever you want. As such, because your image data varies in size at each iteration, this will do very nicely. To access data at any iteration, simply do:
data = img_cell{ii};
ii is the index of the iteration you want to access.
If you want to literally obtain what you are asking for, you can use the eval() function, which takes a string as input that it will evaluate as if it were a line of code. Example:
for i=1:3
data=ones(i); % assign data, 'ones(i)' used as dummy for test
eval(['Img_' num2str(i) '=data;'])
end
However, I would recommend using cell arrays {}, or alternatively the struct function that rayryeng both suggested.

Storing each iteration of a loop in Matlab

I have a 2d matrix (A=80,42), I am trying to split it into (80,1) 42 times and save it with a different name. i.e.
M_n1, M_n2, M_n3, … etc (representing the number of column)
I tried
for i= 1:42
M_n(i)=A(:,i)
end
it didn't work
How can I do that without overwrite the result and save each iteration in a file (.txt) ?
You can use eval
for ii = 1:size(A,2)
eval( sprintf( 'M_n%d = A(:,%d);', ii, ii ) );
% now you have M_n? var for you to process
end
However, the use of eval is not recommanded, you might be better off using cell array
M_n = mat2cell( A, [size(A,1)], ones( 1, size(A,2) ) );
Now you have M_n a cell array with 42 cells one for each column of A.
You can access the ii-th column by M_n{ii}
Generally, doing if you consider doing this kind of things: don't.
It does not scale up well, and having them in one array is usually far more convenient.
As long as the results have the same shape, you can use a standard array, if not you can put each result in a cell array eg. :
results = cell(nTests,1)
result{1} = runTest(inputs{1})
or even
results = cellfun(#runTest,inputs,'UniformOutput',false); % where inputs is a cell array
And so on.
If you do want to write the numbers to a file at each iteration, you could do it without the names with csvwrite or the like (since you're only talking about 80 numbers a time).
Another option is using matfile, which lets you write directly to a variable in a .mat file. Consult help matfile for the specifics.

Matlab - Access index of max value in for loop and use it to remove values from array

I would like to recursively find the maximum value in a series of matrices (column 8, to be specific), then use the index of that maximum value to set all values in the array with index up to the max index to NaN (for columns 14:16). It is straight forward to find the max value and index, but using a for loop to do it for multiple arrays I am stumped.
Here is how I can do it without a for loop:
[C,Max] = max(wy2000(:,8));
wy2000(1:Max,14:16) = NaN;
[C,Max] = max(wy2001(:,8));
wy2001(1:Max,14:16) = NaN;
[C,Max] = max(wy2002(:,8));
wy2002(1:Max,14:16) = NaN;
and so on and so forth...
Here are two ways I have tried using a for loop:
startyear = 2000;
endyear = 2009;
for n=startyear:endyear
currentYear = sprintf('wy%d',n);
[C,Max] = max(currentYear(:,8));
currentYear(1:Max,14:16) = NaN;
end
Here is another way I tried, using the eval function
for n=2000:2009;
currentYear = ['wy' int2str(n)];
var2 = ['maxswe' int2str(n)];
eval([var2 ' = max(currentYear(:,8))']);
end
In both cases, the problem seems to be that MATLAB doesn't recognize the 'currentYear' variable to be the array that corresponds to the wyXXXX that I already have created in my workspace.
Based on Peters answer, here is some more info about my data. I am starting with a matrix of data called all_data which holds 16 columns of data, spanning the time period 1982 - 2012. I am only interested in the period 2000 - 2009, and I am also interested in analyzing each year individually (2000, 2001,...,2009).
To get the data into individual years, I use the following code:
for n=2000:2009;
s = datenum(n-1,10,1);
e = datenum(n,9,30);
startcell = find(TIME(:,7)==s);
endcell = find(TIME(:,7)==e);
var1 = ['wy' int2str(n)];
eval([var1 '= all_data3(startcell:endcell,:)']);
eval(['save ', var1]);
end
For clarification, it is the period 10/1/YEAR1 to 9/30/YEAR2 that I am interested in, and TIME is a matrix holding the dates and times of my data.
So at the end of the above for-loop, I have a new matrix for each water-year (wy). I then want to find the date of maximum snow-accumulation (column 8) and exclude all data prior to that date from my analysis. this is where the original question comes from.
Peter's solution works, but I was hoping to find a more simple solution to find the max date and set the values prior to that date to NaN, without having to declare a bunch of variables (or entries in a cell array).
If I could write a loop that would create the cell array that Peter suggested based on a start and end year, that would make the code transferable to other datasets, but when i try to do this I run into the issue that the index for the cell-array is 1:length(years), but the wy arrays are named according to the actual year, so there is an inconsistency when using the eval function.
Matt
You've discovered the problem with eval and dynamically named variables. They're messy. I'd recommend recoding this as a cell array, with the cell array index being the index for the year:
years = 2000:2009;
wy{1} = wy2000;
wy{2} = wy2001;
% etc...
% Then,
for n=1:length(years)
[C, maxval] = max(wy{n}(:,8));
% etc.
end
You really only need the actual year when you input the data and when you display it. Now, if you're starting from a huge pile of arrays already named this way, that's the time to use eval: to convert them into this form that's easier to use. Just form the eval strings so they read, for example, 'wy{1} = wy2000;'

How can I create/process variables in a loop in MATLAB?

I need to calculate the mean, standard deviation, and other values for a number of variables and I was wondering how to use a loop to my advantage. I have 5 electrodes of data. So to calculate the mean of each I do this:
mean_ch1 = mean(ch1);
mean_ch2 = mean(ch2);
mean_ch3 = mean(ch3);
mean_ch4 = mean(ch4);
mean_ch5 = mean(ch5);
What I want is to be able to condense that code into a line or so. The code I tried does not work:
for i = 1:5
mean_ch(i) = mean(ch(i));
end
I know this code is wrong but it conveys the idea of what I'm trying to accomplish. I want to end up with 5 separate variables that are named by the loop or a cell array with all 5 variables within it allowing for easy recall. I know there must be a way to write this code I'm just not sure how to accomplish it.
You have a few options for how you can do this:
You can put all your channel data into one large matrix first, then compute the mean of the rows or columns using the function MEAN. For example, if each chX variable is an N-by-1 array, you can do the following:
chArray = [ch1 ch2 ch3 ch4 ch5]; %# Make an N-by-5 matrix
meanArray = mean(chArray); %# Take the mean of each column
You can put all your channel data into a cell array first, then compute the mean of each cell using the function CELLFUN:
meanArray = cellfun(#mean,{ch1,ch2,ch3,ch4,ch5});
This would work even if each chX array is a different length from one another.
You can use EVAL to generate the separate variables for each channel mean:
for iChannel = 1:5
varName = ['ch' int2str(iChannel)]; %# Create the name string
eval(['mean_' varName ' = mean(' varName ');']);
end
If it's always exactly 5 channels, you can do
ch = {ch1, ch2, ch3, ch4, ch5}
for j = 1:5
mean_ch(j) = mean(ch{j});
end
A more complicated way would be
for j = 1:nchannels
mean_ch(j) = eval(['mean(ch' num2str(j) ')']);
end
Apart from gnovice's answer. You could use structures and dynamic field names to accomplish your task. First I assume that your channel data variables are all in the format ch* and are the only variables in your MATLAB workspace. The you could do something like the following
%# Move the channel data into a structure with fields ch1, ch2, ....
%# This could be done by saving and reloading the workspace
save('channelData.mat','ch*');
chanData = load('channelData.mat');
%# Next you can then loop through the structure calculating the mean for each channel
flds = fieldnames(chanData); %# get the fieldnames stored in the structure
for i=1:length(flds)
mean_ch(i) = mean(chanData.(flds{i});
end