how to efficiently find the indices?
Afficher commentaires plus anciens
Hi,
I have a matrix of N-by-M with integers. I need to efficiently find the indices for all of the unique elements in the matrix. The solution I have is via a "for" loop:
uM = unique (M(:));
for i = 1 : length(uM)
I(i) = find(M == uM(i));
end
This works fine, but with a large matrix, this is slow. I wonder if there are better solutions. thanks very much!
1 commentaire
Geoff
le 3 Mai 2012
One way to make this code faster without changing anything fundamental would be to preallocate the cell array before your loop:
I = cell(length(uM),1);
Réponse acceptée
Plus de réponses (6)
Leah
le 2 Mai 2012
Matlab has a nice function built in for this
[B,I,J] = UNIQUE(...) also returns index vectors I and J such
that B = A(I) and A = B(J) (or B = A(I,:) and A = B(J,:)).
Andrei Bobrov
le 3 Mai 2012
[uM,n,n] = unique (M(:));
I = accumarray(n,1:numel(n),[],@(x){sort(x)});
2 commentaires
Richard Brown
le 3 Mai 2012
I think even @(x) {x} would meet the brief for your function
Andrei Bobrov
le 3 Mai 2012
Hi Richard! I agree with you.
Richard Brown
le 2 Mai 2012
Depending on whether you want the first or the last occurence
[uM, I] = unique(M, 'first')
[uM, I] = unique(M)
Walter Roberson
le 2 Mai 2012
0 votes
Your suggested code will not work if there are any duplicates, as the find() would return multiple values in that case and multiple values cannot be stored into a single numeric array element.
Have you considered using the second or third return value from unique() ?
Pinpress
le 2 Mai 2012
0 votes
2 commentaires
Oleg Komarov
le 2 Mai 2012
A and J will give you what you want.
Richard Brown
le 2 Mai 2012
Not really - J is just A(:), but with the unique elements replaced with 1:nUnique. So it's no better
Geoff
le 2 Mai 2012
This comes straight out of some of my own code... I guess it's the reverse of what you want though.
uM = unique(M);
I = arrayfun(@(x) find(uM==x,1), M);
For every element in M, it gives an index into uM. I use this to reduce columns of data in a matrix that are common to multiple targets.
So you seem to want: for every element in uM an array of indices into M. The result of course would be a cell array.
This would be:
I = arrayfun(@(x) find(M==x), uM, 'UniformOutput', false);
2 commentaires
Richard Brown
le 2 Mai 2012
I think that's what he was trying before, but found the repeated calls to find to be too slow
Pinpress
le 3 Mai 2012
Catégories
En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!