2016-08-26 1 views
2

У меня есть список из двух столбцов. Первый столбец - это номера предметов, номера вторых сеансов (т. Е. Когда объект приходит во второй раз, номер сеанса равен 2 и т. Д. Для каждого посещения).Удалите строки с тем же первым столбцом и мин. Второй столбец

SubMasterList = [6004 1; 6004 2; 6008 1; 6008 2; 6010 1; 6012 1; 6012 2; 6012 3] 

Я хотел бы SubMasterList, чтобы содержать только 1 строку субъекта с наибольшим номером сеанса (колонка 2). Так, как казаться:

SubMasterList = [6004 2; 6008 2; 6010 1; 6012 3] 

ответ

6

Вы можете использовать sortrows, после чего вы извлечь индексы из этого массива, используя второй выход unique

SubMasterList = [6004 1; 6004 2; 6008 1; 6008 2; 6010 1; 6012 1; 6012 2; 6012 3]; 
tmp = sortrows(SubMasterList,-2); %sort, with descending order to ensure the highest number is on top 
[~,idx,~]=unique(tmp(:,1)); %extract indices 
Result = tmp(idx,:) %index the sorted array to obtain the result 

Result = 
     6004   2 
     6008   2 
     6010   1 
     6012   3 
+1

Это может быть дополнительно улучшено путем удаления 'функции flipud' и используя' -2' вместо '2' в' sortrows' функции, которая будет сортировать строки второго столбца в порядке убывания. –

+0

@Sardar_Usama Я уже искал 'sort'-like' 'descending''; Я не знал, что это сработало. Благодаря! – Adriaan

2

Может быть, не эффективным, как ответ @Adriaan «s:

A = [6004 1; 6004 2; 6008 1; 6008 2; 6010 1; 6012 1; 6012 2; 6012 3]; 

[C,~,ic] = unique(A(:,1)); 
B = A(:,2); 
for ii=1:max(ic) 
    D(ii,1) = max(B(ic==ii)); 
end 
SubMasterList = [C D]; 


SubMasterList = 

     6004   2 
     6008   2 
     6010   1 
     6012   3 
+1

Интересно видеть, что вы использовали все выходы 'unique', кроме того, что я получил. Хороший ответ. – Adriaan

+1

вот что делает каждый ответ «уникальным», :) – NKN

+0

Я должен разницу, но сейчас слишком много сном;) Думаю, это будет иметь заметную разницу только тогда, когда количество строк превышает примерно 10 000 или около того. Ваш код может быть более понятным, чем все мои флип-флоппинг массивов. Точка совершенства: инициализировать 'D'. Вы знаете, насколько он будет большой (т. Е. Размер 'C'), и это будет намного быстрее с большими массивами. – Adriaan

4

То, что вы хотите, почти определение accumarray :-) Просто используйте unique, чтобы получить этикетки на основе первого столбца вашей матрица, и передать, что в качестве первого входа в accumarray:

[x, ~, u] = unique(SubMasterList(:,1)); 
y = accumarray(u, SubMasterList(:,2), [], @max); 
result = [x y]; 
+1

@Adriaan 'tankarray' не является замкнутой петлей в том же смысле, что и' arrayfun'. Это должно быть быстрее, чем 'for' или' arrayfun'. Но кто знает в наши дни, когда петли становятся быстрее с JIT ... –

+0

О, интересно. Я думал, что «накопитель» сделал цикл. Никогда не слишком стара, чтобы учиться. Думаю, – Adriaan

+0

@Adriaan Внутренне, конечно, он должен это сделать. Но у него есть имя для быстрого, в отличие от 'arrayfun' –

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