Nested loops basic problem, please help

1 次查看(过去 30 天)
Sophie
Sophie 2017-7-18
评论: Sophie 2017-7-21
Hello, sorry, it is a basic question, but I am novice and stuck, please help.
I have a 24x2 cell
Mean_block =
[1.5069] [1]
[1.4816] [3]
[1.4784] [2]
[1.4732] [2]
[1.4684] [1]
[1.4450] [3]
[1.4822] [3]
[1.4711] [2]
[1.4786] [3]
[1.4730] [1]
[1.4565] [1]
[1.4565] [1]
[1.4236] [3]
[1.4414] [1]
[1.4388] [2]
[1.4139] [3]
[1.4567] [1]
[1.4482] [3]
[1.4433] [2]
[1.4755] [2]
[1.4992] [2]
[1.4852] [2]
[1.4790] [3]
[1.4544] [1]
I would like to create a cell or matrix with 3 columns (one for each Mean_block(:,2) data; one for 1 , 2 and 3). Then in each corresponding column, I would like to add the corresponding Mean_block(:,1). Like that :
[1.5069] [1.4784] [1.4816]
[1.4684] [1.4732] [1.4450]
...
MY CODE
Emotion_by_Blocks =cell(8:3);
for w= 1:3
for ww= 1:8
for www= 1:24 if Mean_block{www,2} == w; Emotion_by_Blocks (ww,w) = Mean_block (www,1); end end
end
end
OUTCOME
Emotion_by_Blocks =
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
[1.4544] [1.4852] [1.4790]
I think I should not use that many loops or no loop at all to achieve this kind of simple goal but my programming repertory is quite poor, not sure what else I could do.
Any help/comment would very appreciated. Thanks Sophie.

回答(2 个)

Geoff Hayes
Geoff Hayes 2017-7-18
Sophie - there are several ways to solve this problem some of which might involve loops and others that don't. The following is an example that uses one loop.
To make things easier, let's convert your cell array to a numeric array. We can do this as
numericData = cell2mat(Mean_block);
We can then get a list of the unique ids (those elements in your second column) as
ids = unique(numericData(:,2));
If we assume that each id has the same number of elements, then we can instantiate our new array as
Emotion_by_Blocks = zeros(size(numericData(:,1), 1)/length(ids),length(ids));
And we populate it as
for k=1:length(ids)
Emotion_by_Blocks(:,k) = numericData(numericData(:,2) == ids(k),1);
end
So we iterate over each id and determine which row of numericData has that id
numericData(:,2) == ids(k)
This will return a logical array of zeros and ones where a one indicates that that row matches the id of interest. We then extract all elements in the first column of numericData whose id matches the one we want
Emotion_by_Blocks(:,k) = numericData(numericData(:,2) == ids(k),1);

Harish Saranathan
Harish Saranathan 2017-7-18
编辑:Harish Saranathan 2017-7-18
Hello Sophie,
You can avoid for loops altogether by using logical indexing. You can learn more about it here: https://www.mathworks.com/help/matlab/math/matrix-indexing.html
The following code accomplishes the intended task using logical indexing:
originalArray = [1.5069 1;
1.4816 3;
1.4784 2;
1.4732 2;
1.4684 1;
1.4450 3;
1.4822 3;
1.4711 2;
1.4786 3;
1.4730 1;
1.4565 1;
1.4565 1;
1.4236 3;
1.4414 1;
1.4388 2;
1.4139 3;
1.4567 1;
1.4482 3;
1.4433 2;
1.4755 2;
1.4992 2;
1.4852 2;
1.4790 3;
1.4544 1];
newArray = zeros(8,3);
% Pull out elements from column 1 of originalArray whose corresponding
% column 2 is 1, and store them in column 1 of newArray.
newArray(:,1) = originalArray(originalArray(:,2)==1);
% Pull out elements from column 1 of originalArray whose corresponding
% column 2 is 2, , and store them in column 2 of newArray.
newArray(:,2) = originalArray(originalArray(:,2)==2);
% Pull out elements from column 1 of originalArray whose corresponding
% column 2 is 3, and store them in column 3 of newArray.
newArray(:,3) = originalArray(originalArray(:,2)==3);
disp(newArray);
Executing the above code results in the following output:
1.5069 1.4784 1.4816
1.4684 1.4732 1.4450
1.4730 1.4711 1.4822
1.4565 1.4388 1.4786
1.4565 1.4433 1.4236
1.4414 1.4755 1.4139
1.4567 1.4992 1.4482
1.4544 1.4852 1.4790
The above code assumes that the number of elements corresponding to 1, 2 and 3 is the same and is known apriori. Suppose this is not the case, you can use "unique" and "arrayfun" functions. The documentation for these functions can be found here:
To demonstrate this, let us use "originalArray" with some elements corresponding to "2" removed.
originalArray = [1.5069 1;
1.4816 3;
1.4784 2;
1.4684 1;
1.4450 3;
1.4822 3;
1.4786 3;
1.4730 1;
1.4565 1;
1.4565 1;
1.4236 3;
1.4414 1;
1.4139 3;
1.4567 1;
1.4482 3;
1.4433 2;
1.4755 2;
1.4992 2;
1.4852 2;
1.4790 3;
1.4544 1];
"unique" can be used to find out the unique entries in an array - in this case, the second column of originalArray.
>> nUnique = unique(originalCellArray(:,2))
nUnique =
1
2
3
We can now pull out the elements from originalArray corresponding to each number in nUnique and store them in separate cell arrays.
>> newArray = arrayfun(@(in) originalArray(in == originalArray(:,2),1),nUnique','UniformOutput',false)
newArray =
1×3 cell array
[8×1 double] [5×1 double] [8×1 double]
>> newArray{1}
ans =
1.5069
1.4684
1.4730
1.4565
1.4565
1.4414
1.4567
1.4544
>> newArray{2}
ans =
1.4784
1.4433
1.4755
1.4992
1.4852
>> newArray{3}
ans =
1.4816
1.4450
1.4822
1.4786
1.4236
1.4139
1.4482
1.4790
You can notice that the cell arrays are not of the same size.
Harish

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by