una - find matlab
¿Cómo puedo encontrar índices de cada fila de una matriz que tiene un duplicado en matlab? (3)
Quiero encontrar los índices de todas las filas de una matriz que tienen duplicados. Por ejemplo
A = [1 2 3 4
1 2 3 4
2 3 4 5
1 2 3 4
6 5 4 3]
El vector que se devolverá sería [1,2,4]
Una gran cantidad de preguntas similares sugieren el uso de la función unique
, que he intentado pero lo más cerca que puedo llegar a lo que quiero es:
[C, ia, ic] = unique(A, ''rows'')
ia = [1 3 5]
m = 5;
setdiff(1:m,ia) = [2,4]
Pero al usar unique
, solo puedo extraer la segunda, tercera, cuarta ... instancia de una fila, y también necesito obtener la primera. ¿Hay alguna manera de que pueda hacer esto?
NB: Debe ser un método que no implique pasar por las filas, ya que estoy tratando con matrices dispersas grandes.
Otras tres posibilidades:
Clasifique las filas de la matriz (con
sortrows
), detecte filas iguales (condiff
) y utilice la indexación para deshacer la clasificación:[As inds] = sortrows(A); ind = find(all(diff(As)==0,2)); result = inds(union(ind,ind+1));
Compare directamente cada fila con cada otra fila (con
bsxfun
):match = squeeze(all((bsxfun(@eq, A, permute(A, [3 2 1]))), 2)); result = find(any(match - eye(size(A,1))));
Use
pdist
con la distancia de Hamming en lugar debsxfun
:match = ~squareform(pdist(A,''hamming'')); result = find(any(match - eye(size(A,1))));
La ventaja de los enfoques 2 y 3 es que también obtienes una matriz (simétrica), una match
, que te dice qué fila es igual a qué otra fila. Para tu ejemplo,
>> match
match =
1 1 0 1 0
1 1 0 1 0
0 0 1 0 0
1 1 0 1 0
0 0 0 0 1
Qué tal si:
[~, ia, ic] = unique(A, ''rows'')
setdiff(1:size(A,1), ia( sum(bsxfun(@eq,ic,(1:max(ic))))<=1 ))
Una forma de identificar duplicados es aplicar accumarray
en el vector ic
desde unique
. Entonces, setdiff
devolverá la lista completa si los índices de las filas duplicadas.
[~, ia, ic] = unique(A,''rows'')
dupRows = setdiff(1:size(A,1), ia(accumarray(ic,1)<=1) )