2016-09-05 26 views
5

Say mam matrycę A z 2 kolumny - kolumna 1 zawiera Item ID i kolumna 2 zawiera jego waga:Czy istnieje jedna liniówka, która pozwala znaleźć minimum unikatowych jednostek z macierzy wielu wystąpień każdego elementu?

A = [ 
3 5 
2 3 
2 5 
1 4 
3 4 
2 6 
1 9 
3 2 ]; 

Chcę wyjście następująco:

items = [ 
1 4 
2 3 
3 2]; 

Kodeksu chciałbym napisać w tym celu będzie:

items(:,1)=unique(A(:,1)); 
for i=1:size(items,1) 
    temp=A(A(:,1)==items(i,1),:); 
    items(i,2)=min(temp(:,2)); 
end 

items matryca jest wymagane wyjście tutaj.

Zastanawiam się, czy istnieje kod jedno-liniowy, który robi to w MATLAB.

Odpowiedz

8

zakładając twoi Identyfikatory pozycji są liczbami całkowitymi poczynając od jednego, można użyć accumarray:

accumarray(a(:,1), a(:,2), [], @min); 
+0

@Shai Dzięki za rozwiązanie. Twój kod jest natychmiast wykonywany, a moje wykonanie zajmuje około minuty. Czy wiesz, dlaczego istnieje tak duża różnica czasu? – Kristada673

+0

używasz 'unique', który sortuje tablicę - zajmuje O (nlogn). Następnie powtarzasz ponownie po wszystkich elementach w 'A' i dla każdej pozycji porównujesz ją z' itemami (i, 1) 'trwa to O (n^2). Używając "accumarray" uważam, że jest O (n). – Shai

+0

@Shai 'unique' kończy się natychmiast. Jest to pętla 'for', która zabiera czas. I tak, prawdopodobnie wynika to z O (n^2) vs O (n), o którym wspomniałeś. Wciąż próbując zrozumieć twój kod, jak działa "accumarray" :-) – Kristada673

3

Zastosowanie sortrows:

B = sortrows(A); 
A_min = B([true; diff(B(:,1))~=0], :) 

A_min = 

    1  4 
    2  3 
    3  2 

sortrows sortuje matrycy w górę, zgodnie z pierwszej kolumny, a następnie drugim. Użyj tego nowego posortowanego wektora i wyodrębnij pierwszy wiersz wraz ze wszystkimi wierszami, w których zmieni się pierwsza kolumna (1, 2, 3).

[true; diff(B(:,1))~=0] to wektor zawierający boolean [true false false true ...]. true wskazuje, gdzie zmieniają się elementy pierwszej kolumny. Jest używany jako mapa logiczna do indeksowania oryginalnej tablicy.

Powinieneś wiedzieć, że:

x = [1 2 3 4]; 
idx = [true false false true]; 
x(idx) = 
    1 4 
+0

@ Kristada673 Spróbuj wyszukać w funkcji 'diff'. To rozwiązałoby twój problem. Wierzę, że – patrik

1

Jeśli masz dostęp do przetwarzania obrazu przybornika można zrobić to:

[unique(A(:,1)),[regionprops(A(:,1),A(:,2),'MinIntensity').MinIntensity]'] 
+0

ta składnia działa tylko dla oktawy, a nie dla Matlaba. – Shai

+0

@Shai proszę mi powiedzieć, jaka część kodu nie może być uruchomiona w Matlab – rahnema1

+2

W Matlab, nie można odwoływać się do wyjścia funkcji: nie można uzyskać dostępu do pola '.MinIntensity' niejawnego wyjścia' regionprops (...) '.Musisz przypisać wyjście do zmiennej i dopiero wtedy uzyskać dostęp do pola tej tablicy struct – Shai