2010-03-25 15 views
8

interpolazione grandi serie di datiinterpolando grandi set di dati al volo

Ho un grande insieme di dati di circa 0.5million record che rappresentano il tasso di cambio tra l'USD/GBP nel corso di un dato giorno.

Ho un'applicazione che vuole essere in grado di rappresentare questi dati o forse un sottoinsieme. Per ovvi motivi, non voglio tracciare 0,5 milioni di punti sul mio grafico.

Quello che mi serve è un dataset più piccolo (100 punti o giù di lì) che rappresenti accuratamente (il più possibile) i dati dati. Qualcuno sa di modi interessanti e performanti per ottenere questi dati?

Cheers, Karl

+1

puoi chiarire "rappresenta" - intendi solo visivamente o ai fini dell'esecuzione dei calcoli? – Carl

+0

Il risultato finale sarebbe un set di dati di un tipo che potrebbe quindi essere elaborato e grafico – Karl

+1

Suoni come un lavoro per R! – Joel

risposta

3

Un pensiero è usare il DBMS per comprimere i dati per voi utilizzando una query appropriata. Qualcosa sulla falsariga di averlo prendere un mediano per una gamma specifica, una pseudo-query:

SELECT truncate_to_hour(rate_ts), median(rate) FROM exchange_rates 
WHERE rate_ts >= start_ts AND rate_ts <= end_ts 
GROUP BY truncate_to_hour(rate_ts) 
ORDER BY truncate_to_hour(rate_ts) 

Dove truncate_to_hour è qualcosa di appropriato per DBMS. O un approccio simile con un qualche tipo di funzione per segmentare il tempo in blocchi univoci (come ad esempio intorno all'intervallo di 5 minuti più vicino), o un'altra funzione matematica per aggregare il gruppo che è appropriato al posto della mediana. Data la complessità della procedura di segmentazione temporale e l'ottimizzazione del DBMS, potrebbe essere più efficiente eseguire una query su una tabella temporanea con il valore temporale segmentato.

1

Qualcosa come RRDTool farebbe quello che ti serve automaticamente: tutorial dovrebbe iniziare, e drraw traccerà i dati.

Io uso questo al lavoro per cose come i grafici di errore, non ho bisogno di risoluzione di 1 minuto per un periodo di tempo di 6 mesi, solo per le ultime ore. Dopo di ciò ho una risoluzione di 1 ora per alcuni giorni, quindi una risoluzione di 1 giorno per alcuni mesi.

1

Se si voleva scrivere il proprio, una soluzione ovvia sarebbe quella di rompere il set di record in blocchi di numero di punti fissi, per cui il valore sarebbe la media (media, mediana, ... sceglierne uno) . Questo ha il probabile vantaggio di essere il più veloce e mostra le tendenze generali.

Ma manca il dramma delle zecche dei prezzi. Una soluzione migliore probabilmente riguarderebbe la ricerca dei punti di flesso, quindi la selezione tra di loro usando le finestre scorrevoli. Questo ha il vantaggio di visualizzare meglio gli eventi reali del giorno, ma sarà più lento.

4

Esistono diversi metodi statistici per la riduzione di un set di dati di grandi dimensioni in un dataset più piccolo e più facile da visualizzare. Non è chiaro dalla tua domanda quale statistica riassuntiva desideri. Ho appena pensato che tu voglia vedere come cambia il tasso di cambio in funzione del tempo, ma forse sei interessato a quanto spesso il tasso di cambio supera un certo valore, o qualche altra statistica che non sto considerando.

Sintetizzando un andamento nel tempo

Ecco un esempio utilizzando il metodo lowess in R (dalla documentazione sul scatter plot smoothing): controlli f

> library(graphics) 
# print out the first 10 rows of the cars dataset 
> cars[1:10,] 
    speed dist 
1  4 2 
2  4 10 
3  7 4 
4  7 22 
5  8 16 
6  9 10 
7  10 18 
8  10 26 
9  10 34 
10 11 17 

# plot the original data 
> plot(cars, main = "lowess(cars)") 
# fit a loess-smoothed line to the points 
> lines(lowess(cars), col = 2) 
# plot a finger-grained loess-smoothed line to the points 
> lines(lowess(cars, f=.2), col = 3) 

Il parametro quanto strettamente la regressione adatta a i tuoi dati. Usa un po 'di attenzione con questo, perché desideri qualcosa che si adatti esattamente ai tuoi dati senza sovraffollamento.Piuttosto che velocità e distanza, puoi tracciare il tasso di cambio in funzione del tempo.

È anche semplice accedere ai risultati del livellamento. Ecco come fare:

> data = lowess(cars$speed, cars$dist) 
> data 
$x 
[1] 4 4 7 7 8 9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 16 16 17 17 17 18 18 18 18 19 19 
[38] 19 20 20 20 20 20 22 23 24 24 24 24 25 

$y 
[1] 4.965459 4.965459 13.124495 13.124495 15.858633 18.579691 21.280313 21.280313 21.280313 24.129277 24.129277 
[12] 27.119549 27.119549 27.119549 27.119549 30.027276 30.027276 30.027276 30.027276 32.962506 32.962506 32.962506 
[23] 32.962506 36.757728 36.757728 36.757728 40.435075 40.435075 43.463492 43.463492 43.463492 46.885479 46.885479 
[34] 46.885479 46.885479 50.793152 50.793152 50.793152 56.491224 56.491224 56.491224 56.491224 56.491224 67.585824 
[45] 73.079695 78.643164 78.643164 78.643164 78.643164 84.328698 

L'oggetto dati che torni contiene le voci denominate xey, che corrispondono ai valori X e Y passato alla funzione lowess. In questo caso, xey rappresentano la velocità e dist.

0

Come creare un wrapper di enumerazione/iteratore. Non ho familiarità con Java, ma si possono sguardi simile a:

class MedianEnumeration implements Enumeration<Double> 
{ 
    private Enumeration<Double> frameEnum; 
    private int frameSize; 

    MedianEnumeration(Enumeration<Double> e, int len) { 
     frameEnum = e; 
     frameSize = len; 
    } 

    public boolean hasMoreElements() { 
     return frameEnum.hasMoreElements(); 
    } 

    public Double nextElement() { 
     Double sum = frameEnum.nextElement(); 

     int i; 
     for(i=1; (i < frameSize) && (frameEnum.hasMoreElements()); ++i) { 
      sum += (Double)frameEnum.nextElement(); 
     } 

     return (sum/i); 
    } 
} 
1

L'approccio ingenuo è semplicemente calcolando una media per TimeInterval corrispondente ad un pixel.

http://commons.wikimedia.org/wiki/File:Euro_exchange_rate_to_AUD.svg

Questo non mostra flunctuations. Suggerirei anche di calcolare la deviazione standard in ogni intervallo di tempo e tracciare anche quello (essenzialmente rendendo ogni pixel più alto di un singolo pixel). Non sono riuscito a trovare un esempio, ma so che Gnuplot può farlo (ma non è scritto in Java).

+0

La soluzione _really_ naive sarebbe semplicemente prendere ogni valore N-esimo. Mi aspetto di prendere, ad es. ogni 100 ° valore in un set di dati da 100k fornirebbe comunque un'immagine molto buona della cronologia del valore misurato e nessun altro metodo potrebbe toccarlo in termini di prestazioni. –

+0

Vero. Sembra che la velocità sia più importante dell'accuratezza dei pixel. –

+0

Questa risposta sembra stranamente ... familiare. ;] – CPerkins