Извлечь "n" строк для каждого идентификатора в матрице - MATLAB - PullRequest
1 голос
/ 29 октября 2011

У меня есть матрица, которая имеет несколько строк на один идентификатор.Мне нужно извлечь только скажем. 4 последних строки на ID.Идентификационные столбцы состоят из 2-х кол:

mat = [ ...
        2222 1   734771 0.11
        2222 1   734772 0.22
        2222 1   734773 0.33
        2222 1   734774 0.44
        2222 1   734775 0.55
        5555 3   734771 0.11
        5555 1   734772 0.12
        5555 1   734773 0.13
      ] ;

ответ ->% [2222 1 734772 0,22;2222 1734773 0,33;2222 1734774 0,44;2222 1 734775 0,55]

Я ценю векторизованный подход.Спасибо и счастливого Хэллоуина!

Ответы [ 3 ]

2 голосов
/ 29 октября 2011

Вот эффективное решение с использованием функций UNIQUE и ACCUMARRAY :

%# sample matrix, sorted by first column
mat = [randi([1 5],[20 1]) (1:20)' rand(20,1)];   %'
mat = sortrows(mat);

%# extract last N rows from each unique ID
N = 4;
[~,~,subs] = unique( mat(:,1) );                 %# index into unique values
fcn = @(x){ x(max(1,end-N+1):end) };             %# at most last N values
ind = accumarray(subs, 1:numel(subs), [max(subs) 1], fcn);
ind = cell2mat( ind(cellfun(@numel,ind) >= 4) ); %# keep only those with 4+ count
result = mat(ind,:)

Используя третий вывод функции UNIQUE, мы получаем для каждой строкииндекс в список уникальных идентификаторов.Затем мы распределяем индексы строк в ячейки (массив ячеек) на основе этих индексов.Мы берем последние четыре индекса из каждого бина и фильтруем их с менее чем 4 случаями.Затем мы объединяем их все в один вектор индексов строк.Наконец, мы используем его для получения соответствующих строк из исходной матрицы.

Используя приведенный выше пример, мы генерируем следующую матрицу:

mat =
            1            2      0.70199
            1            6      0.46313
            1            7      0.98821
            1           12      0.15645
            1           13      0.67037
            1           16      0.86966
            2            8      0.63491
            2            9     0.076501
            2           15      0.55076
            2           17      0.44727
            2           19      0.30587
            3            5      0.91502
            3           10      0.97322
            3           20      0.48231
            4            3      0.45633
            4            4      0.12363
            4           11      0.18319
            4           14      0.36045
            5            1      0.36708
            5           18      0.63084

, и в результате получилось:

result =
            1            7      0.98821
            1           12      0.15645
            1           13      0.67037
            1           16      0.86966
            2            9     0.076501
            2           15      0.55076
            2           17      0.44727
            2           19      0.30587
            4            3      0.45633
            4            4      0.12363
            4           11      0.18319
            4           14      0.36045
0 голосов
/ 29 октября 2011
X=[];
id=ones(size(mat,1),1)==1;
for n=1:4
   [~, m, ~]=unique(mat(id,1:2),'rows');
   X=[X; mat(m,:)];
   id(m)=0;
end
return X

(В своем примере ответа вы не вернули ни одной из 5555 строк, но я предполагаю, что вы хотите их.)

0 голосов
/ 29 октября 2011

Не самая эффективная реализация, которую вы видели, но она работает:

a = [1 1 1 1 2 2 2 2 3 3 ];
b = unique(a);

for i = 1:length(b)
   c = b(i);
   ind = find(a==c);
   last4 = ind(end-1:end) %adjust how many elements you want
end

Очевидно, что если у вас есть матрица, вам придется добавить индекс столбца, если вас волнует

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...