How to order values within a cell array more efficiently??

조회 수: 4 (최근 30일)
Antonio Espana
Antonio Espana 2013년 11월 14일
댓글: Antonio Espana 2013년 11월 15일
I have a 3x12 cell array called "ratings"
ratings= {'AAA','AA','A','A-','BBB-','BB+','BB','BB-','B+','B','B-','CCC+';
'A','A-','AA','AAA','B','B+','B-','BB','BB+','BB-','BBB-','CCC+';
1,1,1,3,11,16,18,1,1,17,16,14};
  • The first row of the array has the ratings in the desired order
  • The second row has the ratings disordered
  • The third row contains a number associated with the ratings in the second row
I wrote the following code:
orderedratings=cell(1,length(ratings))
for i=1:length(ratings);
for j=1:length(ratings)
if strcmp(ratings(1,i),ratings(2,j))==1
orderedratings(i)=ratings(3,j);
end
end
end
and it allows me to reorder the third row in respect to the ordered first row, such that:
orderedratings={1,6,8,2,18,3,1,21,17,12,10,1}
Is there a way to do the same more efficiently, or another way without "for" conditionals?? It is very much appreciated a different appoach.
Antonio Espana
  댓글 수: 2
Ben Petschel
Ben Petschel 2013년 11월 15일
If I run your code I get a different result:
orderedratings = { 3, 1, 1, 1, 16, 1, 1, 17, 16, 11, 18, 14}
Not sure how you obtained {1,6,8,...}
Antonio Espana
Antonio Espana 2013년 11월 15일
Hi Ben thanks for the heads up, you are right the result i wrote is completely wrong and your result is the right one. It is not a problem with the code but a blunder on my side cause i wrote the result of a different ratings array.

댓글을 달려면 로그인하십시오.

채택된 답변

Ben Petschel
Ben Petschel 2013년 11월 15일
The following should work regardless of the ordering of the two rows:
[~,idx] = ismember(ratings(1,:),ratings(2,:));
orderedratings = ratings(3,idx)
  댓글 수: 1
Antonio Espana
Antonio Espana 2013년 11월 15일
Hi Ben
Also tested this code and is very fast and elegant, with all this ideas i can get rid of a lot of conditionals thanks.
Antonio

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Simon
Simon 2013년 11월 14일
Hi!
orderedratings = cellfun(@(x) ratings{3,x}, ...
cellfun(@(x) strcmp(x,ratings(2,:)), ratings(1,:), 'UniformOutput', false));
It takes about 2/3 of the time, but it is not very easy to read ...
  댓글 수: 7
Simon
Simon 2013년 11월 15일
orderedratings{1,7} is a 1x2 cell because the 7th element in the first row of ratings 'BB' is found in the 8th and 10th element of the second row, while the 8th element in the first row of ratings 'BB-' wasn't found at all in the second row. Great, isn't it? ;-)
Antonio Espana
Antonio Espana 2013년 11월 15일
Thank you very much i overlooked the fact that your example had two cells with the same value whereas my normal ratings arrays never have repeated values. Now, that could be useful way to control my arrays hehe.
Antonio

댓글을 달려면 로그인하십시오.


Azzi Abdelmalek
Azzi Abdelmalek 2013년 11월 14일
편집: Azzi Abdelmalek 2013년 11월 15일
[~,~,idx]=unique(ratings(1,:));
out=ratings(3,idx)
ADD
If the second row is not sorted
[idx2,idx2]=sort(ratings(2,:));
[~,~,idx12]=unique(ratings(1,:));
idx12=idx2(idx12);
out=ratings(3,idx12);
  댓글 수: 5
Azzi Abdelmalek
Azzi Abdelmalek 2013년 11월 15일
Look at ADD in case the second row is not sorted
Antonio Espana
Antonio Espana 2013년 11월 15일
Silly me now i get what you mean by sorted, my second row is always sorted because is the result of another implementation of the unique function in another part of my code, i scrambled the second row a bit and with the ADD code still manages to work. Thanks
Antonio

댓글을 달려면 로그인하십시오.


Azzi Abdelmalek
Azzi Abdelmalek 2013년 11월 15일
In case the second row is not sorted
[idx1,idx1]=sort(ratings(1,:));
[idx2,idx2]=sort(ratings(2,:));
[kk,kk]=sort(idx2);
[idx,idx]=sort(idx1(kk));
orderedratings = ratings(3,idx);%
  댓글 수: 3
Azzi Abdelmalek
Azzi Abdelmalek 2013년 11월 15일
After speed test, this code seems slightly faster then my previous answer
Antonio Espana
Antonio Espana 2013년 11월 15일
it is indeed :-)

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Hypothesis Tests에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by