2015-09-23 2 views
2

Если у меня есть массив [1 2 3 4 3 5 6 7 8 7], я бы хотел найти список уникальных записей: [3 7]. Я не могу найти простой способ сделать это. Есть идеи?Найти не уникальные элементы массива в Matlab

Обновление: Я хотел бы иметь универсальное решение, которое также будет работать с массивом ячеек строк.

+0

Возможный дубликат http://stackoverflow.com/questions/5385651/determining-the-number-of-occurrences-of-each-unique-element-in-a-vector – gregswiss

+1

@gregswiss: Мне нужен список а не как часто они встречаются. Кроме того, решения в связанном вопросе не применимы к нечисловым массивам. – texnic

ответ

5

Если А имеет длину п, то могут найти индексы в A первого вхождения каждой записи и удалить их из A:

A = [1 2 3 4 3 5 6 7 8 7]; 
n=length(A); 
[~,IA,~] = unique(A); 
out = unique(A(setdiff((1:n),IA))) 
+0

Удивительный! Он работает, и это действительно опрятное решение. – texnic

1

Один подход с unique и histc -

[unqA,~,id] = unique(A); 
out = unqA(histc(id,1:max(id))>1) 

Или использовать accumarray вместо histc -

out = unqA(accumarray(id(:),1)>1) 

bsxfun Или используйте -

out = unqA(sum(bsxfun(@eq,id(:),1:max(id(:)).'))>1) 

Примеры трасс -

1) Числовые массивы случай -

>> A 
A = 
    6  3  7  7  4  3  8  5  2  3  1 
>> [unqA,~,id] = unique(A); 
>> unqA(histc(id,1:max(id))>1) 
ans = 
    3  7 
>> unqA(accumarray(id(:),1)>1) 
ans = 
    3  7 
>> unqA(sum(bsxfun(@eq,id(:),1:max(id(:)).'))>1) 
ans = 
    3  7 

массивы 2) Сотовый случай -

>> A = {'apple','banana','apple','mango','ball','cat','banana','apple'}; 

>> [unqA,~,id] = unique(A); 
>> unqA(histc(id,1:max(id))>1) 
ans = 
    'apple' 'banana' 
>> unqA(accumarray(id(:),1)>1) 
ans = 
    'apple' 'banana' 
>> unqA(sum(bsxfun(@eq,id(:),1:max(id(:)).'))>1) 
ans = 
    'apple' 'banana' 
+0

Хорошие решения тоже. Я буду придерживаться принятого ответа, поскольку Стив имеет более низкую репутацию, но вы получаете свой голос :) Спасибо за добавление примеров. – texnic

-1

Другой подход с использованием sort и diff:

As = sort(A); 
out = unique(As([false diff(As)==0])); 
+3

Кажется, что более двух вхождений числа дадут дубликаты записей на выходе, если я не пропустил что-то. – Divakar

+0

@ Дивакар Нет, вы ничего не пропустите, вы абсолютно правы. Спасибо, Стив отредактировал мой ответ. – Bentoy13

0

Поскольку вы запрашиваете более общее решение, вот что должно быть легко адаптировано к другим типам данных. По сравнению с другими это также (п) решение O - но недостатком является медленная Matlab зацикливание на большом массиве элементов ...

A = [1 2 3 4 3 5 6 7 8 7]; 
dupes = []; 

map = containers.Map('KeyType', class(A), 'ValueType' , 'logical'); 
for i=1:numel(A) 
    if map.isKey(A(i)) 
     dupes = [dupes A(i)]; 
    else 
     map(i) = true; 
    end   
end 
1
x=[1 2 3 4 3 5 6 7 8 7]; 
y=x; 
[~,ind,~]=unique(y); 
y(ind)=[]; 

у есть неуникальные записи.

+0

Хотя этот код может помочь решить проблему, предоставляя дополнительный контекст относительно _why_ и/или _how_, он отвечает на вопрос, значительно улучшит его долгосрочную ценность. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение. –

Смежные вопросы