Vettorizzare un ciclo for

di il
4 risposte

Vettorizzare un ciclo for

Ciao a tutti,
ho una matrice 1440x26 di stringhe 'Vero','Falso' e voglio sapere quante sono le righe di questa matrice in cui compare la scritta 'Vero' nella colonna 3, 5, 14, 15... (solo in alcune specifiche colonne).

io ho scritto un programma (funzionante) che prevede un ciclo if annidato in un ciclo for, in cui pre-allocando la variabile n_min_hole ne incremento il valore ogni volta che una riga obiettivo viene rilevata. Il problema è che questa operazione richiede molto tempo ed essendo solo parte di un programma più complesso ne risulta che la durata dell'elaborazione ne risente di molto. Qualcuno mi sa suggerire un modo migliore per fare questa operazione? E possibile solo tramite creazione di vettori e sfruttando la funzione 'any'?

Grazie

PS sperando possa essere utile allego il programma che ho scritto

n_min_hole=0;
for pp=1:(length(data_daily(:,1)))
hole_3=strcmp(holes(pp+(i-1)*1440,3),'True');
hole_5=strcmp(holes(pp+(i-1)*1440,5),'True');
hole_11=strcmp(holes(pp+(i-1)*1440,11),'True');
hole_12=strcmp(holes(pp+(i-1)*1440,12),'True');
hole_15=strcmp(holes(pp+(i-1)*1440,15),'True');
hole_16=strcmp(holes(pp+(i-1)*1440,16),'True');
hole_19=strcmp(holes(pp+(i-1)*1440,19),'True');
hole_20=strcmp(holes(pp+(i-1)*1440,20),'True');
hole_23=strcmp(holes(pp+(i-1)*1440,23),'True');
hole_24=strcmp(holes(pp+(i-1)*1440,24),'True');
hole_14=strcmp(holes(pp+(i-1)*1440,14),'True');
hole_17=strcmp(holes(pp+(i-1)*1440,17),'True');
hole_21=strcmp(holes(pp+(i-1)*1440,21),'True');
hole_25=strcmp(holes(pp+(i-1)*1440,25),'True');
hole=[hole_3 hole_5 hole_11 hole_12 hole_15 hole_16 hole_19 hole_20 hole_23 hole_24 hole_14 hole_17 hole_21 hole_25];
    if hole(1)==1 || hole(2)==1 || hole(3)==1 || hole(4)==1 || hole(5)==1 || hole(6)==1 || hole(7)==1 || hole(8)==1 || hole(9)==1 || hole(10)==1 || hole(11)==1 || hole(12)==1 || hole(13)==1 || hole(14)==1 
        n_min_hole=n_min_hole+1;
    else 
    end
end

4 Risposte

  • Re: Vettorizzare un ciclo for

    Hai scritto di avere "un programma (funzionante) , ma nel codice che hai pubblicato, non è chiaro come accedi alle varie righe e sembrano esserci le condizioni per ottenere dei messaggi di errore; ad esempio:

    Le stringhe "True" e "False" hanno lunghezza diversa e non possono essere memorizzate in una matrice di caratteri.
    Che tipo di matrice è "holes"? Un cellarray?
    
    hole_3=strcmp(holes(pp+(i-1)*1440,3),'True');
    
    [*] la "i" non è definita
    [*] se "i=0" pp+(i-1)*1440 assume un valore negativo il che dovrebbe generare un messaggio di errore
    [*] per valori di "i" maggiori di 1 "pp+(i-1)*1440" dalla seconda iterazione assume valori maggiori di 1440 il che supera la dimensione della matrice e dovrebbe generare un messaggio di errore
    [*] non è chiaro quale sia la dimensione della matrice "data_daily", soprattutto in relazione alla matrice "holes"
  • Re: Vettorizzare un ciclo for

    Sì hai ragione, data daily è un altra matrice delle stesse dimensioni contenente dei dati mentre i è la variabile contatore del ciclo for in cui l'intero codice che ho postato è contenuto(questa operazione va ripetuta circa 150 volte). Purtroppo non mi è possibile pubblicare l'intero codice, quello che ho messo speravo potesse servire a chiarire il mio obiettivo nel caso non fossi stato abbastanza esaustivo nella spiegazione. Vorrei sostituire questo frammento di codice con una più efficace.

    Questo è il programma se fosse isolato, dove holes è la matrice contenente le stringhe di vero/falso(cell array):
    
    n_min_hole=0;
    for pp=1:(length(holes(:,1)))
    hole_3=strcmp(holes(pp,3),'True');
    hole_5=strcmp(holes(pp,5),'True');
    hole_11=strcmp(holes(pp,11),'True');
    hole_12=strcmp(holes(pp,12),'True');
    hole_15=strcmp(holes(pp,15),'True');
    hole_16=strcmp(holes(pp,16),'True');
    hole_19=strcmp(holes(pp,19),'True');
    hole_20=strcmp(holes(pp,20),'True');
    hole_23=strcmp(holes(pp,23),'True');
    hole_24=strcmp(holes(pp,24),'True');
    hole_14=strcmp(holes(pp,14),'True');
    hole_17=strcmp(holes(pp,17),'True');
    hole_21=strcmp(holes(pp,21),'True');
    hole_25=strcmp(holes(pp,25),'True');
    hole=[hole_3 hole_5 hole_11 hole_12 hole_15 hole_16 hole_19 hole_20 hole_23 hole_24 hole_14 hole_17 hole_21 hole_25];
        if hole(1)==1 || hole(2)==1 || hole(3)==1 || hole(4)==1 || hole(5)==1 || hole(6)==1 || hole(7)==1 || hole(8)==1 || hole(9)==1 || hole(10)==1 || hole(11)==1 || hole(12)==1 || hole(13)==1 || hole(14)==1 
            n_min_hole=n_min_hole+1;
        else 
        end
    end
  • Re: Vettorizzare un ciclo for

    Supponendo che la matrice "holes" sia in realtà un cellarray come, ad esempio:
    
    holes={'Vero' 'Vero' 'Falso' 'Vero' 'Vero'
           'Vero' 'Falso' 'Falso' 'Falso' 'Vero'
           'Falso' 'Falso' 'Falso' 'Falso' 'Falso'
           'Vero' 'Vero' 'Vero' 'Vero' 'Falso'
    }
    
    se vuoi contare il numero di righe nelle quali la stringa "true" compaia nelle colonne 2, 3 o 4 puoi risolvere il problema senza loop con tre istruzioni.
    I commenti all'interno del codice dovrebbero spiegare sufficientemente i vari passaggi
    
    % Individua la stringa "Falso" in tutta la matrice
    % Il risultato viene slvato in un cellarray
    %
    Falso_cell=strfind(holes(:),'Falso')
    %
    % Crea una matrice (di tipo logical" delle stesse dimensoni di "holes" nella quale:
    % 0 corrisponde alla presenza della stringa "Falso" nella matrice "holes" 
    % 1 corrisponde alla presenza della stringa "Vero" nella matrice "holes"
    %
    Vero_mat=reshape(cellfun(@isempty,Falso_cell),size(holes))
    %
    % Conta in quante righe, per le colonne selezionate (2 3 4 in questo esempio)
    % comnpare la stringa "Vero".
    % Il conteggio sfrutta il fatto che la funzione "any", chiamata con secondo parametro "2"
    % ritorna 1 se almeno un valore su un ariga risulta diverso da 0
    %
    z=sum(any(Vero_mat(:,[2 3 4]),2))
    
  • Re: Vettorizzare un ciclo for

    Ha funzionato alla perfezione e con una riduzione dei tempi impressionante!
    Grazie mille utilissimo come sempre!
Devi accedere o registrarti per scrivere nel forum
4 risposte