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

1 visualizzazione (ultimi 30 giorni)
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

Risposta accettata

Stephen23
Stephen23 il 9 Mag 2017
Modificato: Stephen23 il 9 Mag 2017
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 Commenti
Stephen23
Stephen23 il 9 Mag 2017
Modificato: Stephen23 il 9 Mag 2017
@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

Accedi per commentare.

Più risposte (1)

KL
KL il 9 Mag 2017
Modificato: KL il 9 Mag 2017
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 Commenti
Stephen23
Stephen23 il 9 Mag 2017
Modificato: Stephen23 il 9 Mag 2017
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 il 9 Mag 2017
Cool, I just wanted to stick to strcmp to compare ref and mess. I appreciate you took time to compare our codes

Accedi per commentare.

Categorie

Scopri di più su Interactive Control and Callbacks in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by