Voici une solution efficace en utilisant UNIQUE et ACCUMARRAY fonctions:
%# 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,:)
en utilisant la troisième sortie de la fonction UNIQUE, nous obtenons pour chaque ligne l'index dans la liste des identifiants uniques. Ensuite, nous distribuons les indices de ligne dans des groupes (tableau de cellules) basés sur ces indices. Nous prenons les quatre derniers indices de chaque bin, et filtrons ceux avec moins de 4 occurrences. Nous les combinons ensuite en un seul vecteur d'indices de ligne. Enfin, nous l'utilisons pour obtenir les lignes correspondantes de la matrice d'origine.
En utilisant l'exemple ci-dessus, nous générons la matrice suivante:
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
et le résultat était:
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
Merci Amro. Pour une raison quelconque, votre code ne fonctionne pas correctement pour l'exemple ci-dessus. J'ai modifié fnc unique pour utiliser 2 cols au lieu d'un, mais il continue à ramasser 5555 (qui devrait être abandonné car il a compté <4 lignes). Je vais apprécier. – Maddy
@Maddy: Eh bien, il n'était pas clair à partir de votre description initiale si vous vouliez garder des lignes avec moins de 4 occurrences d'ID uniques .. De toute façon, voir mon édition récente pour le correctif – Amro
merci! J'ai besoin de mieux comprendre accumarray. J'ai conçu une nouvelle approche en utilisant reshape() etc mais votre solution est beaucoup plus courte et élégante. – Maddy