2013-07-11 2 views
2

dire que j'ai un ensemble de données:Matlab - ne garder que 24 jours où des valeurs existent

Jday = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:... 
    datenum('2009-01-05 23:00','yyyy-mm-dd HH:MM'); 
DateV = datevec(Jday); 
DateV(4,:) = []; 
DateV(15,:) = []; 
DateV(95,:) = []; 

Dat = rand(length(Jday),1) 

Comment est-il possible de supprimer tous les jours qui ont moins de 24 mesures. Par exemple, dans le premier jour, il n'y a que 23 mesures, donc je devrais supprimer toute la journée, comment pourrais-je répéter cela pour tout le tableau?

+0

Pourriez-vous dire quelque chose sur ce que vous essayez d'accomplir ? Il est possible qu'une approche entièrement différente convienne mieux à votre tâche. – Nigel

+0

J'essaie de calculer la plage de température pour un jour donné où 'Dat' est la température, afin de garder cette cohérence entre tous les jours, je veux seulement garder des jours qui ont des mesures 24 heures, c'est-à-dire pas de points manquants . – Emma

Répondre

1

Une solution rapide est de groupe par année, mois, jour avec unique(), puis compter l'observation par jour avec accumarray() et exclut ceux qui ont moins de 24 obs avec deux étapes de indexation logique:

% Count observations per day 
[unDate,~,subs] = unique(DateV(:,1:3),'rows'); 
counts = [unDate accumarray(subs,1)] 
counts = 
     2009   1   1   22 
     2009   1   2   24 
     2009   1   3   24 
     2009   1   4   24 
     2009   1   5   23 

Ensuite, appliquer des critères pour les chefs d'accusation et retriev e index logique

% index only those that meet criteria 
idxC = counts(:,end) == 24 
idxC = 
     0 
     1 
     1 
     1 
     0 

% keep those which meet criteria (optional, for visual inspection) 
counts(idxC,:) 
ans = 
     2009   1   2   24 
     2009   1   3   24 
     2009   1   4   24 

Enfin, retrouvez les membres de Dat qui entrent dans la counts sélectionnée avec une deuxième série de indexinf logique par ismember():

idxDat = ismember(subs,find(idxC)) 
Dat(idxDat,:) 
+0

Donc, cela vous donne les jours individuels qui ont l'ensemble des 24 valeurs, alors afin de sélectionner «Dat» pour ces jours, nous devrions sélectionner les lignes qui sont égales à ces comptes? – Emma

+0

J'ai édité la réponse pour inclure un second tour de l'indexation logique qui filtre 'Dat'. – Oleg

1

Plutôt longue réponse, mais je pense que cela devrait être utile. Je le ferais en utilisant containers.Map. Peut-être y a-t-il un moyen plus rapide, mais peut-être que pour l'instant celui-ci sera bon.

Jday = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:... 
    datenum('2009-01-05 23:00','yyyy-mm-dd HH:MM'); 

DateV = datevec(Jday); 
DateV(4,:) = []; 
DateV(15,:) = []; 
DateV(95,:) = []; 


% create a map 
dateMap = containers.Map(); 



% count measurements in each date (i.e. first three columns of DateV) 
for rowi = 1:1:size(DateV,1) 

    dateRow = DateV(rowi, :); 
    dateStr = num2str(dateRow(1:3)); 

    if ~isKey(dateMap, dateStr) 
     % initialize Map for a given date with 1 measurement (i.e. our 
     % counter of measuremnts 
     dateMap(dateStr) = 1; 
     continue; 
    end 
    % increment measurement counter for given date 
    dateMap(dateStr) = dateMap(dateStr) + 1; 
end 


% get the dates 
dateStrSet = keys(dateMap); 




for keyi = 1:numel(dateStrSet) 

    dateStrCell = dateStrSet(keyi); 
    dateStr = dateStrCell{1}; 

    % get number of measurements in a given date 
    numOfmeasurements = dateMap(dateStr); 

    % if less then 24 do something about it, e.g. save the date 
    % for later removal from DateV 
    if numOfmeasurements < 24 
     fprintf(1, 'This date has less than 24 measurement: %s\n', dateStr); 
    end 
end 

Le résultat est:

This date has less than 24 measurement: 2009  1  1 
This date has less than 24 measurement: 2009  1  5 
Questions connexes