2010-03-25 5 views
8

große Daten-SetsInterpolier große Daten-Sets auf der Fly

Interpolier Ich habe eine große Datenmenge von etwa 0.5million Aufzeichnungen, die den Wechselkurs zwischen USD/GBP über den Verlauf eines bestimmten Tages.

Ich habe eine Anwendung, die diese Daten grafisch darzustellen oder vielleicht eine Teilmenge in der Lage sein will. Aus offensichtlichen Gründen möchte ich keine 0,5 Millionen Punkte auf meiner Grafik darstellen.

Was ich brauche, ist ein kleiner Datensatz (100 Punkte oder so), die genau (wie möglich) die angegebenen Daten darstellt. Kennt jemand irgendwelche interessante und performante Art, wie diese Daten erreicht werden können?

Cheers, Karl

+1

können Sie verdeutlichen "darstellt" - meinen Sie nur visuell oder zum Zwecke der Durchführung von Berechnungen auf? – Carl

+0

Endergebnis wäre ein Datensatz eines Typs, der dann verarbeitet und grafisch dargestellt werden könnte – Karl

+1

Klingt wie ein Job für R! – Joel

Antwort

3

Ein Gedanke ist das DBMS verwenden, um die Daten zu komprimieren für Sie eine entsprechende Abfrage. Etwas entlang der Linien, die sie mit einem mittleren für einen bestimmten Bereich übernehmen, eine pseudo-Abfrage:

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) 

Wo truncate_to_hour etwas passend zu Ihrem DBMS ist. Oder ein ähnlicher Ansatz mit einer Art Funktion, um die Zeit in einzelne Blöcke zu segmentieren (z. B. auf das nächste 5-Minuten-Intervall) oder eine andere mathematische Funktion, um die Gruppe zu gruppieren, die anstelle des Median angemessen ist. Angesichts der Komplexität der Zeitsegmentierungsprozedur und der Optimierung Ihres DBMS ist es möglicherweise effizienter, eine Abfrage für eine temporäre Tabelle mit dem segmentierten Zeitwert auszuführen.

1

Etwas wie RRDTool würde tun, was Sie automatisch benötigen - die tutorial sollten Sie beginnen, und drraw wird die Daten grafisch darstellen.

Ich benutze dies bei der Arbeit für Dinge wie Fehler Grafiken, ich brauche keine Auflösung 1 Minute für einen 6-Monats-Zeitraum, nur für die letzten paar Stunden. Danach habe ich für ein paar Tage eine 1-Stunden-Lösung, dann für ein paar Monate eine 1-Tages-Lösung.

1

Wenn Sie Ihre eigenen schreiben wollten, wäre eine naheliegende Lösung, Ihren Datensatz in feste Punkte zu zerlegen, für die der Wert der Durchschnitt wäre (Mittelwert, Median, ... wählen Sie einen). . Dies hat den wahrscheinlichen Vorteil, dass es der schnellste ist, und zeigt allgemeine Trends.

Aber es fehlt das Drama der Preisticks. Eine bessere Lösung würde wahrscheinlich darin bestehen, nach den Wendepunkten zu suchen und dann unter Verwendung von Schiebefenstern auszuwählen. Dies hat den Vorteil, dass die tatsächlichen Ereignisse des Tages besser angezeigt werden, aber langsamer.

4

Es gibt verschiedene statistische Methoden für eine große Datenmenge auf eine kleinere reduzieren, einfache Datenmenge zu visualisieren. Es ist nicht klar aus Ihrer Frage, welche zusammenfassende Statistik Sie wollen. Ich habe gerade angenommen, dass Sie sehen möchten, wie sich der Wechselkurs als Funktion der Zeit ändert, aber vielleicht interessieren Sie sich dafür, wie oft der Wechselkurs über einen bestimmten Wert steigt, oder eine andere Statistik, die ich nicht in Betracht ziehe.

einen Trend im Laufe der Zeit zusammenfassend

Hier ist ein Beispiel der lowess Verfahren in R mit (aus der Dokumentation auf scatter plot smoothing):

> 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) 

Die f Kontrollen Parameter, wie eng die Regression passt zu deine Daten. Nutzen Sie dabei etwas Nachdenklichkeit, denn Sie möchten etwas, das Ihren Daten ohne Überanpassung genau entspricht.Statt Geschwindigkeit und Distanz können Sie den Wechselkurs gegen die Zeit darstellen.

Es ist auch einfach, auf die Ergebnisse der Glättung zuzugreifen. Hier ist, wie das tun:

> 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 

Das Datenobjekt, das Sie zurückkommen enthält Einträge namens x und y, die die x entsprechen und y-Werte in die Lowess Funktion übergeben. In diesem Fall stehen x und y für Geschwindigkeit und Dist.

0

Wie wäre es, Enumeration/Iterator Wrapper zu machen. Ich bin nicht vertraut mit Java, aber es kann ähnelt:

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

Der naive Ansatz ist einfach ein durchschnittliches pro timeinterval Berechnung zu einem Pixel entspricht.

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

Dies zeigt nicht flunctuations. Ich würde vorschlagen, auch die Standardabweichung in jedem Zeitintervall zu berechnen und das auch zu zeichnen (im Wesentlichen jedes Pixel höher als ein einzelnes Pixel zu machen). Ich konnte kein Beispiel finden, aber ich weiß, dass Gnuplot das kann (aber nicht in Java geschrieben ist).

+0

Die _really_ naive Lösung wäre, einfach jeden N-ten Wert zu nehmen. Ich erwarte z.B. Jeder 100-te Wert in einem 100k-Datensatz würde immer noch ein sehr gutes Bild der Messwerthistorie liefern und keine andere Methode könnte es in Bezug auf die Leistung erreichen. –

+0

Wahr. Es scheint, dass die Geschwindigkeit wichtiger ist als die Pixelgenauigkeit. –

+0

Diese Antwort scheint seltsam ... vertraut. ;] – CPerkins