How to manipulate arrays inside a cell array?

Hi,
I have a cell array(1x316) which contains 316 double numeric arrays of various sizes like
{74845x2 double}, {81032x2 double}, {87351x2 double},.....
sample of one array inside the cell-array :
{74845x2}=
0.194 0.0043
0.116 0.0040
0.118 0.0041
0 0.0044
0 0.0037
0 0.0042
0.045 0.0041
0.151 0.0043
0
0.231 0.0040
0
.....................
.....................
Now, Steps to be taken: 1)
Check if the first column values are non-zero,if it is true then, find difference of elements in first and second column separately.
EDIT
There are two cases here:
case i)If there are more than one non-zero elements together in first column then,
find the maximum and minimum values in the group and compute difference as (max-min).
d11 = 0.194(max among 0.118, 0.116, 0.194)- 0.116(Min value of those)
d12 = 0.0043(max among 0.0041, 0.0040, 0.0043)- 0.0040(min of those)
d21 = 0.151-0.045 d22 = 0.0043-0.0041
case ii)If there is only one non-zero element in the first column, no need to take difference.The output should be same.
d31 = 0.231 d32 = 0.0040
2)At last, remove all the zero values from all arrays in the cell.
This way, i need to compute differences among non-zero elements from all the 316 arrays in the cell array and save the results in a new cell array of original size 1x316.
Please help me out on this.
Thanks in advance!

4 个评论

Where do the d21 = 0.231-0.045 d22 = 0.0043-0.0040 values come from? Should this be d21 = 0.116-0.045 ?
Hi Stephen, the values in each column of the arrays are in random order.So, the maximum and minimum values need to be fixed first and then differences are computed.
d21 = 0.231( max. of 0.045,0.151,0.231,0.106) and 0.045(min of those)
Ah, you are taking the min and max of each group of non-zero values. Is this correct?
Yes, thats correct.What is making me tough here is, I need to compute differences in each group between 0's.I can't take difference at once removing all 0's here.
e.g.
d11 = 0.194-0.116 d12 = 0.0043-0.0040
d21 = 0.231-0.045 d22 = 0.0043-0.0040
d31,d32; d41,d42 , all values are calculated step by step whenever it is non-zeros.

请先登录,再进行评论。

 采纳的回答

Perhaps you should try something like this:
X = cellfun(@(m)m(:,1)>0,C,'UniformOutput',false);
D = cellfun(@(m,x)abs(diff(m(x,:),1,1)),C,X,'UniformOutput',false);
(It could be done in one cellfun call, but this clearly separates the logical condition and the diff operation).
EDIT to place the values into groups (based on non-zero values in the first column), and then calculate the max and min of each group:
M = [0.194,0.0043;0.116,0.0040;0,0.0044;0,0.0037;0,0.0042;0.045,0.0041;0.151,0.0043;0.231,0.0040;0.106,0.0043;0,0.0040];
C = {M};
% Preallocate an output cell array:
D = cell(numel(C),2);
for k = 1:numel(C)
% locate non-zero values in first column:
idx = 0<C{k}(:,1);
% number those values according to each group:
idg = cumsum(0<diff([false;idx]));
% get max and min of each group, for 1st and 2nd column:
mx1 = accumarray(idg(idx),C{k}(idx,1),[],@max);
mx2 = accumarray(idg(idx),C{k}(idx,2),[],@max);
mn1 = accumarray(idg(idx),C{k}(idx,1),[],@min);
mn2 = accumarray(idg(idx),C{k}(idx,2),[],@min);
% calculate difference of max and min:
D{k,1} = mx1-mn1;
D{k,2} = mx2-mn2;
end

12 个评论

This looks pretty much helpful.But i need to remove data values from both columns in arrays if the first column has 0's and the size of the output cell array should be 1x316(same as before).
That is what my code does: it ignores all columns where the first row is zero. Do you see idx? It selects the rows where the first column is non-zero.
The output is currently a cell array with two columns (for each column of the input data). You have not said what order or arrangement you want these numeric values in, and I cannot read your mind... however I will guess that you want a numeric matrix with two columns (of the differences) in each cell of the output array. You just need to change the output D like this:
D = cell(size(C)); % same size as the input C
for ...
...
D{k} = [mx1-mn1,mx2-mn2]; % two columns in one matrix
end
Hi Stephen, I really appreciate your help.I have recently edited my question in more details above.I hope you will find it more clear.
@Jung BC: you have significantly edited your question, and given lots of new information and new example values.
This always turns into a game of tennis: original question, original answer, changed question, changed answer, changed question, changed answer... and so on, ad infinitum. This happens occasionally on this forum, and it is very tiring for us volunteers. It is not a fun game to play.
I solved your original question, which you then accepted. I would be happy to help you with any further questions that you might have, but I am not going to play a game of tennis with you when you continually change your question. If my answer does not work or does not solve your original question, then please let me know and I will correct it.
If you make some minor changes to a question then add them as comments or else clearly marked with "EDIT". Otherwise ask a new question, with a link to the first question.
Hi Stephen, I have no any intension to play game with change in questions and change in answers.
I am just trying to elaborate my question in details.Your earlier solution didn't correctly solve my problem but i just thought i should try myself with your concept and finally when i verified my output data values,it went in wrong turn.
So i again edited my question here.
"Your earlier solution didn't correctly solve my problem" but it did solve your question. And you accepted it because it solved your question.
Try this:
M = [0.194,0.0043; 0.116,0.0040; 0.118,0.0041; 0,0.0044; 0,0.0037; 0,0.0042; 0.045,0.0041; 0.151,0.0043; 0,0; 0.231,0.0040; 0,0];
C = {M};
% Preallocate an output cell array:
D = cell(size(C));
for k = 1:numel(C)
% locate non-zero values in first column:
idx = 0<C{k}(:,1);
% number those values according to each group:
idg = cumsum(0<diff([false;idx]));
% count number of elements in each group:
num = histc(idg(idx),unique(idg));
idn = num==1;
% get max and min of each group, for 1st and 2nd column:
mx1 = accumarray(idg(idx),C{k}(idx,1),[],@max);
mx2 = accumarray(idg(idx),C{k}(idx,2),[],@max);
mn1 = accumarray(idg(idx),C{k}(idx,1),[],@min);
mn2 = accumarray(idg(idx),C{k}(idx,2),[],@min);
% calculate difference of max and min:
df1 = mx1-mn1;
df2 = mx2-mn2;
% if the group has only one row, use those values:
df1(idn) = mx1(idn);
df2(idn) = mx2(idn);
% allocate to output cell array:
D{k} = [df1,df2];
end
where
>> D{:}
ans =
0.078 0.0003
0.106 0.0002
0.231 0.004
I have no idea what you mean by "2)At last, remove all the zero values from all arrays in the cell." What zeros, and how do you want them removed? The first step was to identify groups of non-zero elements, so what zeros are left?
Hi Stephen! some error: Index exceeds matrix dimensions!It's small thing to fix but i couldn't. Thanks once again for your help.
My code works without error on the example data that you have given us. If you have some other data that it does not work on then you can either:
  • show or upload that data here (upload using the paperclip button).
  • send it to me via brainwaves.
I recommend that you try the first option, as my mind-reading skills are not very good these days.
Due to size limits of file, i am unable to attach my data here. Here is the source of error in my data:
df1(idn) = mx1(idn);
df2(idn) = mx2(idn);
Size of df1 is 7255x1 double, and size of idn is 7256x1 logical. Hence its showing ''Index exceeds matrix dimensions'' while debugging. Could you please suggest how can i fix it?
This error occurs when there are leading zeros in the first column of the input numeric matrix. You can fix this bug by changing this one line of code:
num = histc(idg(idx),1:max(idg));
Many many thanks to you! I appreciate your great support!It worked !
My pleasure! It must be my lucky day, having the same question accepted twice :)

请先登录,再进行评论。

更多回答(1 个)

Write a function that does this for a single element of the cell array and then use cell fun If you can write the function as an inline function that will be nice, otherwise write an m-file to do this. As an example
fh = @(x) abs(x(:,1) - x((:,2)) % difference between largest and smallest
OUT = cellfun(fh, YourCellArray)

类别

帮助中心File Exchange 中查找有关 Matrix Indexing 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by