Imaginez que j'ai deux tableaux:
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
Je veux trouver les indices des valeurs de b dans a (seulement le premier coup), c'est-à-dire:
c = [3, 6, 5];
Existe-t-il un moyen simple, natif Matlab, de le faire sans faire de boucles ni chercher.
J'ai essayé d'utiliser find () avec:
find(a == b)
et cela fonctionnerait si vous faisiez ceci:
for i = 1:length(b)
index = find(a == b(i));
c = [c, index(1)]
end
Mais ce serait idéal pour que ce soit plus facile alors.
Ceci est en fait construit dans ismember
. Vous avez juste besoin de définir le bon drapeau, alors il s’agit d’un one-liner et vous n’avez pas besoin de arrayfun. Les versions plus récentes que R2012b utilisent ce comportement par défaut.
À l'origine, ismember
renverrait la dernière occurrence s'il y en a plusieurs, le drapeau R2012a oblige celle-ci à renvoyer la première.
Voici mes résultats de test:
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];
[~,c] = ismember(b,a,'R2012a');
>> c
c =
3 6 5
Vous pouvez facilement compresser votre boucle for avec arrayfun en une ligne simple:
arrayfun(@(x) find(a == x,1,'first'), b )
voir aussi Réponse de Scenia pour les nouvelles versions de matlab (> R2012b).
Ceci est un correctif à l'approche ismember
que @Pursuit a suggéré. De cette façon, il gère plusieurs occurrences de l'un des nombres et renvoie le résultat dans le bon ordre:
[tf,loc] = ismember(a,b);
tf = find(tf);
[~,idx] = unique(loc(tf), 'first');
c = tf(idx);
Le résultat:
>> c
c =
3 6 5
Vous pouvez essayer ceci:
[c,ind_a] = intersect(a,b)
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];
[r c]=find(bsxfun(@eq,a,b')');
[~,ia,~]=unique(c,'first');
>> r(ia)
ans =
3
6
5
Remarque: j'ai ajouté un 6
supplémentaire à la fin de a
pour montrer que seule la première occurrence de chaque valeur était trouvée.
Avez-vous essayé ismember
?
c_logical_mask = ismember(a, b);
ou
c_indexes = find(ismember(a, b));
Similaire à @ tmpearce's answer , mais peut-être plus rapidement:
[valid, result] = max(bsxfun(@eq, a(:), b(:).')); %'// max finds first occurrence
result = result(valid); %// this is necessary in case some value of b is not in a
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');
Matlab nécessite a et b doivent être des vecteurs colonne, d’où la transposition.