How to obtain a numeric vector with the position of elements of an array regarding another array?

1 回表示 (過去 30 日間)
I have many pairs of arrays (one is the reference and other a with the same elements but with different position) and I need a numeric vector with the position of the elements in the array.
For example, this will be my references:
ref1={'a' 'b' 'c'};
ref2={'a' 'c' 'c' 'c' 'b'};
ref3={'b' 'b' 'c' 'a'};
ref4={'a' 'b' 'c' 'd'};
and this the same arrays but sorted randomly
messy1={'b' 'a' 'c'};
messy2={'c' 'c' 'c' 'b' 'a'};
messy3={'c' 'a' 'b' 'b'};
messy4={'a' 'b' 'c' 'd'};
I would like to obtain something like this:
positionVector1=[2 1 3];
positionVector2=[2 3 4 5 1];
positionVector3=[3 4 1 2];
positionVector4=[1 2 3 4];
the previous examples were just the general idea but the arrays from which I need a numeric vector are like this:
ref={'10fthf[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'atp[m]'};
messy={'10fthf[m]' 'atp[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]'};
positionVector=[1 6 2 3 4 5];
Could you help me with this, thanks in advance!
note: the repeated elements are always together but I need them with a different value in the vector

採用された回答

Stephen23
Stephen23 2017 年 5 月 9 日
編集済み: Stephen23 2017 年 5 月 9 日
Creating numbered variables is not a good code design decision, so the first thing we should do is store that data in nested cell arrays:
C = {{'a' 'b' 'c'};
{'a' 'c' 'c' 'c' 'b'};
{'b' 'b' 'c' 'a'};
{'a' 'b' 'c' 'd'}};
D = {{'b' 'a' 'c'};
{'c' 'c' 'c' 'b' 'a'};
{'c' 'a' 'b' 'b'};
{'a' 'b' 'c' 'd'}};
[~,idc] = cellfun(@sort,C,'uni',0);
[~,idd] = cellfun(@sort,D,'uni',0);
[~,idd] = cellfun(@sort,idd,'uni',0);
idx = cellfun(@(c,d)c(d),idc,idd,'uni',0);
and tested:
>> idx{1}
ans =
2 1 3
>> idx{2}
ans =
2 3 4 5 1
>> idx{3}
ans =
3 4 1 2
>> idx{4}
ans =
1 2 3 4
  2 件のコメント
German Preciat Gonzalez
German Preciat Gonzalez 2017 年 5 月 9 日
It worked, but I gave bad examples... sorry about that, Now I update them
Stephen23
Stephen23 2017 年 5 月 9 日
編集済み: Stephen23 2017 年 5 月 9 日
@German Preciat Gonzalez: Note that my answer is much simpler than the one that you accepted:
>> ref={'10fthf[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'atp[m]'};
>> messy={'10fthf[m]' 'atp[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]' 'glu_L[m]'};
>> [~,idr] = sort(ref);
>> [~,idm] = sort(messy);
>> [~,idm] = sort(idm);
>> idr(idm)
ans =
1 6 2 3 4 5
My answer is also four times faster (1000 iterations):
Elapsed time is 1.7631 seconds. % KL's code
Elapsed time is 0.448025 seconds. % my code

サインインしてコメントする。

その他の回答 (1 件)

KL
KL 2017 年 5 月 9 日
編集済み: KL 2017 年 5 月 9 日
in = cellfun(@strcmp, repmat(ref1,numel(messy1),1), repmat(messy1',1,numel(ref1)))
[I,~]=find(in'>0);
I'
for repeating elements as in ref2,you need to get rid of the repeating indices as well,
[b,m1,n1] = unique(I','first');
[c1,d1] =sort(m1);
b = b(d1)
  5 件のコメント
Stephen23
Stephen23 2017 年 5 月 9 日
編集済み: Stephen23 2017 年 5 月 9 日
See my answer for a simpler solution. My answer uses fewer commands and is four times faster than KL's answer (1000 iterations):
Elapsed time is 1.7631 seconds. % KL's answer
Elapsed time is 0.448025 seconds. % my answer
KL
KL 2017 年 5 月 9 日
Cool, I just wanted to stick to strcmp to compare ref and mess. I appreciate you took time to compare our codes

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by