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.

Community Treasure Hunt

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

Start Hunting!

Translated by