2011-10-28 57 views
1

我有一個矩陣,每個ID有多個行。我需要僅提取每個ID的最後一行。 ID COLS由2列數:爲矩陣中的每個ID提取「n」行 - MATLAB

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 1 734773 0.33; 2222 1 734774 0.44; 2222 1 734775 0.55]

我會欣賞一個量化的方法。萬聖節快樂!

回答

2

下面是使用UNIQUE和一個有效的解決方案個功能:

%# 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,:) 

採用獨特功能的第三輸出,我們得到每一行的索引唯一ID列表。然後,我們將行索引分配到基於這些下標的分箱(單元陣列)中。我們從每個垃圾箱中取出最後四個指數,並對少於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

謝謝Amro。出於某種原因,上面的示例代碼無法正常工作。我已經修改了獨特的fnc來使用2列而不是1列,但它仍然在拾取5555(它應該被刪除,因爲它的計數<4行)。應該感激。 – Maddy

+0

@Maddy:從您的初始描述中不清楚您是否希望保留少於4個唯一ID發生的行..無論如何,請參閱我最近編輯的修復程序 – Amro

+0

,謝謝!我需要更徹底地理解accumarray。我使用reshape()等設計了一種新方法,但您的解決方案要短得多且優雅。 – Maddy

0

不是你見過的最有效的實施,但它的工作原理:

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 

顯然,如果你有一個矩陣,你將不得不如果你關心

0
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

嗨人造人,您的答覆表示感謝。我忽略了'5555',因爲它在示例中具有<4行! – Maddy

相關問題