2010-09-02 42 views
7

Ho una serie di celle ciascuna contenente una sequenza di valori come vettore di riga. Le sequenze contengono alcuni valori mancanti rappresentati da NaN.MATLAB: utilizzo dell'interpolazione per sostituire i valori mancanti (NaN)

Vorrei sostituire tutti i NaN utilizzando una sorta di metodo di interpolazione, come posso farlo in MATLAB? Sono aperto anche ad altri suggerimenti su come gestire questi valori mancanti.

Considerare questi dati di esempio per illustrare il problema:

seq = {randn(1,10); randn(1,7); randn(1,8)}; 
for i=1:numel(seq) 
    %# simulate some missing values 
    ind = rand(size(seq{i})) < 0.2; 
    seq{i}(ind) = nan; 
end 

le sequenze risultanti:

seq{1} 
ans = 
    -0.50782  -0.32058   NaN  -3.0292  -0.45701  1.2424   NaN  0.93373   NaN -0.029006 
seq{2} 
ans = 
     0.18245  -1.5651 -0.084539  1.6039  0.098348  0.041374  -0.73417 
seq{3} 
ans = 
      NaN   NaN  0.42639  -0.37281  -0.23645  2.0237  -2.2584  2.2294 

Edit:

Sulla base delle risposte, penso che ci sia stato un confusione: ovviamente non sto lavorando con dati casuali, il codice mostrato sopra è semplicemente un esempio di come t i dati sono strutturati.

I dati effettivi sono una forma di segnali elaborati. Il problema è che durante l'analisi, la mia soluzione fallirebbe se le sequenze contengono valori mancanti, quindi la necessità di filtraggio/interpolazione (ho già considerato l'utilizzo della media di ogni sequenza per riempire gli spazi vuoti, ma spero in qualcosa di più potente)

+1

Nel tuo esempio, penso che ti sarebbe difficile trovare un modo per interpolare i valori mancanti. L'interpolazione richiede che ci sia una sorta di relazione tra i punti di dati. Spesso è possibile che provengano da una serie temporale (quindi una buona ipotesi è che la parte mancante possa essere dedotta dai punti vicini). Nei tuoi dati di esempio stai cercando di indovinare un "coin-flip" basato solo su altri coin-flip. Se puoi darci maggiori informazioni sul tuo esempio specifico, possiamo aiutarti di più. – JudoWill

+1

@JudoWill: Penso che stia usando solo dati casuali come esempio per le persone con cui giocare. – gnovice

risposta

8

Bene, se si sta lavorando con i dati delle serie temporali, è possibile utilizzare la funzione di interpolazione incorporata di Matlab.

Qualcosa di simile dovrebbe funzionare per la tua situazione, ma dovrai personalizzarlo un po '... cioè. se non si dispone di un campionamento con spaziatura uguale, sarà necessario modificare la riga times.

nseq = cell(size(seq)) 
for i = 1:numel(seq) 
    times = 1:length(seq{i}); 
    mask = ~isnan(seq{i}); 
    nseq{i} = seq{i}; 
    nseq{i}(~mask) = interp1(times(mask), seq{i}(mask), times(~mask)); 

end 

Avrai bisogno di giocare con le opzioni di interp1 per capire quali funzionano meglio per la situazione.

+0

grazie, nel mio caso ho bisogno di cambiare il vettore 'times' dato che i valori sono registrati su base 3 secondi – Dave

+0

... Ora che ci sto pensando, non importa fino a quando le sequenze sono ugualmente campionate non è vero? – Dave

+0

sì, purché siano ugualmente campionati non ha molta importanza ... ma cerco di essere il più esplicito possibile. – JudoWill

0

Come dice JudoWill, è necessario assumere una sorta di relazione tra i dati.

Un'opzione banale sarebbe calcolare la media delle serie totali e utilizzare quelle per i dati mancanti. Un'altra opzione banale sarebbe prendere la media dei valori precedente e successivo.

Ma stai molto attento a questo: se ti mancano i dati, è generalmente meglio gestire i dati mancanti, piuttosto che recuperare dati falsi che potrebbero rovinare la tua analisi.

1

Se si ha accesso allo strumento di identificazione del sistema , è possibile utilizzare la funzione MISDATA per stimare i valori mancanti. Secondo il documentation:

Questo comando interpola linearmente valori mancanti per stimare il primo modello . Quindi, utilizza questo modello per stimare i dati mancanti come parametri minimizzando l'output errori di predizione ottenuti dai dati ricostruiti .

In sostanza l'algoritmo si alterna tra la stima dei dati mancanti e la stima dei modelli, in modo simile all'algoritmo Expectation Maximization (EM).

Il modello stimato può essere uno qualsiasi dei modelli lineari idmodel (AR/ARX/..) oppure, se non specificato, utilizza un modello di spazio degli stati di ordine predefinito.

Ecco come applicarla ai dati:

for i=1:numel(seq) 
    dat = misdata(iddata(seq{i}(:))); 
    seq{i} = dat.OutputData; 
end 
6

userei inpaint_nans, uno strumento progettato per sostituire gli elementi nan in 1-D o 2-d matrici per interpolazione.

seq{1} = [-0.50782 -0.32058 NaN -3.0292 -0.45701 1.2424 NaN 0.93373 NaN -0.029006]; 
seq{2} = [0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417]; 
seq{3} = [NaN NaN 0.42639 -0.37281 -0.23645 2.0237]; 

for i = 1:3 
    seq{i} = inpaint_nans(seq{i}); 
end 

seq{:} 
ans = 
-0.50782 -0.32058 -2.0724 -3.0292 -0.45701 1.2424 1.4528 0.93373 0.44482 -0.029006 

ans = 
    0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417 

ans = 
    2.0248 1.2256 0.42639 -0.37281 -0.23645 2.0237 
+1

+1 grazie ai trucioli di legno – Dave

0

consideri il seguente esempio

X = alcune serie Nx1 Y = F (X) con qualche NaNs in esso

quindi utilizzare

X1 = X (trovare (~ isNaN (Y))); Y1 = Y (trova (~ isnan (Y)));

Ora interpolare su X1 e Y1 per calcolare tutti i valori a tutti X.

0

Usa griddedInterpolant

Ci

anche alcune altre funzioni come interp1. Per i grafici curvi spline è il metodo migliore per trovare i dati mancanti.

Problemi correlati