Arrange cell matrix and get the sum

Hi,
"out" cell matrix has 1x365 cells. I have few questions about dealing with cells.
1) I need to delete cells from 361 to 365 in the "out" cell matrix. How can I do that in MATLAB?
2) After deleting, I need to get the sum like this. For example, from cell 1 - 8.
cell1 cell2 .....cell8 sum
0.0 0.1 0.0 0.1
0.0 0.2 0.5 0.7
0.0 0.1 0.1 0.2
.
.
For example,
for ii=1:8:360
sumout=sum(out{1,ii}{1,3});
end
But, this does not give the sum for all rows. Can someone help me?
Thanks in advance.

 Accepted Answer

Stephen23
Stephen23 on 12 Mar 2015
Edited: Stephen23 on 12 Mar 2015
Putting lots of scalar values in a cell array is a waste of MATLAB's operation vectorizing abilities and this is why you are finding this task so difficult. I will use a simple numeric array, as this makes the doing these kind of operations much easier. Putting things in cell arrays is what you do when you have to, not for some trivial scalar values like this.
>> A = rand(365,1);
>> B = reshape(A(1:360),[],8);
>> sum(B,2)
ans =
4.4687
3.694
4.5899
3.4787
...
3.5861
3.7248
3.8888
5.2515
This code takes the first 360 values in the numeric array, arrange them into a matrix where each row has eight values. It then sums each row to give the final values in a 45x1 vector. And see how much easier it is to work with numeric arrays rather than cell arrays! You can convert the cell array to a numeric array using cell2mat(X), where X is the cell array.

8 Comments

Thanks. But I cannot convert my "out" cell to matrix.
Concatenate the cell arrays in out together, this will make your life a million times easier:
out = vertcat(out{:});
A = cell2mat(out(:,3));
Hi Stephen,
When I do the vertcat for the original "out" cell array, below image shows how it looks.
Array A has all 3rd col of "out" and has 18863565 rows. But when I do
B = reshape(A(1:360),[],8);
it only creates 45 x 8 of for the 3rd col of first row of "out". But, I need to have 45 x 8 matrices for all the rows (3rd col) in out matrix. I think I need to have 1 x 365 cell matrix with each cell has 45 x 8 cells.
What's the easiet way to achieve this?
Damith,
One thing you need to realize at this point is that you did not include nearly complete enough information in your initial post. We had no idea whatsoever that there was a deep underlying structure inside your cell array.
This is frustrating for people trying to help you, because you keep trickling out a bit more information each time. You would probably be done by now, if you had been more complete in your initial question.
@cyclist,
I know this could be frustrating. Thanks for your willingness to understand and I appreciate that. But, I am trying to achieve my ultimate goal of creating a netCDF file using MATLAB. Since I have not done that in MATLAB, I am trying to figure it out through reading online materials.
Let me elaborate here: The first task I realized is to create a 3D array of time, lat, lon of precipitation field. To achieve that, I have hundreds of .csv files (one file is for time (3hrs) in year folders. For example in year 1998 Jan 01 00 time step file name: TRMM_1998_01_0100_newntcl.csv. I have year folders from 1998 to 2014. The last 2 digits on the file name are for 3hr time intervals. Next time is, TRMM_1998_01_0103_newntcl.csv and so on. So, I was able to figure out to read multiple .csv files in one folder in MATLAB and stored them in a cell array.
That is my "out" cell matrix.
My first objective is to create netCDF file year by year. So, I first picked year 1998. First, I need to sum 3hr time intervals for a day e.g. from 00 to 21. That's what I was trying to do through my original post.
In 1998 folder, I have 365 csv files, but I am interested in summing 3hr file for a complete day. Since, I have complete 3hr time interval files upto Feb 14 (TRMM_1998_02_1421_newntcl.csv) that's why I entered the end data here: (See the code below, Stpehen Cobeldick helped here)
yr=1998;
nd=(datenum(1998,2,14,21,0,0)-datenum(1998,1,1,0,0,0))*24/3;
dn=datevec(datenum(yr,1,1,[0:3:nd*3].',0,0));
dn(:,5:6)=[];
dnT=dn(:,4)'; % dnT = 360 here
then Stephen suggested the code below to get the sum
out = vertcat(out{:});
A = cell2mat(out(:,3));
B = reshape(A(1:360,[],8);
C=sum(B,2);
When I do the vertcat for the original "out" cell array, below image shows how it looks.
Array A has all 3rd col of "out" and has 18863565 rows. But when I do
B = reshape(A(1:360),[],8);
it only creates 45 x 8 of for the 3rd col of first row of "out". But, I need to have 45 x 8 matrices for all the rows (3rd col) in out matrix. I need to have 1 x 365 cell matrix with each cell has 45 x 8 cells.
Hope I explained well here. Any help is appreciated.
Thanks again.
Stephen23
Stephen23 on 17 Mar 2015
Edited: Stephen23 on 18 Mar 2015
@Damith: the screen-shots are lovely, but they are no substitute for some real data that we can work with ourselves. It is difficult to give advice when the descriptions change: the original question indicates scalar values in the cells, now they each turn out to have 51681 values in them.
How do you convert a vector of 51681 values into a 45x8 matrix? What happens to the remaining 51321 values?
@Stephen,
Please disregard my original post as I used arbitrary values just for the demonstration purpose. That's my bad. Please see the attached TRMM_1998_01_0100_newntcl.csv file.
Each csv file has 3 columns and 51681 rows. That's exactly what I want. I need to store the remaining values too and to get the daily sum.
For example daily sum (1998 Jan 01) for 51681 lat, lon points =
TRMM_1998_01_0100_newntcl.csv(:,3) +
TRMM_1998_01_0103_newntcl.csv(:,3) +
TRMM_1998_01_0106_newntcl.csv(:,3) +
TRMM_1998_01_0109_newntcl.csv(:,3) +
TRMM_1998_01_0112_newntcl.csv(:,3) +
TRMM_1998_01_0115_newntcl.csv(:,3) +
TRMM_1998_01_0118_newntcl.csv(:,3) +
TRMM_1998_01_0121_newntcl.csv(:,3)
In MATLAB addition of two vectors is an element-wise operation: because the third-column of each of file TRMM_1998_01_0XXX_newntcl.csv is a 51681x1 size numeric vector, the end result will also be a single 51681x1 vector. If this is what you want, then you can simply add the data in a loop. If not, then you need to specify how the data should be handled.
This code, based on your earlier comment, shows how you can get the data during each iteration:
filePattern = fullfile(myFolder, '*.csv');
csvFiles = dir(filePattern);
for k = 1:length(csvFiles)
fid(k) = fopen(fullfile(myFolder,csvFiles(k).name));
out{k} = textscan(fid(k),'%s%s%f','delimiter',',');
fclose(fid(k));
dat = out{k}{3};
end

Sign in to comment.

More Answers (1)

% Make up some data that seems to be like yours
rng 'default'
out = num2cell(rand(1,365));
% Convert from cell array to numeric
out_numeric = cell2mat(out);
% Trim the unwanted
trimmed_out = out_numeric(1:360);
% Reshape to 45x8
reshaped_out = reshape(trimmed_out,45,8);
% Sum
summed_out = sum(reshaped_out,2);

1 Comment

my out is a cell matrix which I obtained through this:
myFolder = 'C:\Users\Desktop\test';
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
filePattern = fullfile(myFolder, '*.csv');
csvFiles = dir(filePattern);
for k = 1:length(csvFiles)
fid(k) = fopen(fullfile(myFolder,csvFiles(k).name));
out{k} = textscan(fid(k),'%s%s%f','delimiter',',');
fclose(fid(k));
end
cell2mat(out) does not work for me. I get an rrror message: (See the image of my cell matrix)
Error using cell2mat (line 52)
Cannot support cell arrays containing cell arrays or
objects.

Sign in to comment.

Categories

Asked:

on 12 Mar 2015

Edited:

on 18 Mar 2015

Community Treasure Hunt

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

Start Hunting!