2016-04-07 9 views
1

ich einen DatenrahmenWie iterieren ich über eine Deedle Serie <Datetime, Serie <Datetime, ObjectSeries <string>>

// Create a dataframe containing the Open, High, Low, and Close 
let ohlc = 
cl 
|> Frame.sliceCols ["Open"; "High"; "Low"; "Close"; "Volume"] 

mit dem resultierenden Ausgang mit erstellt habe: Eröffnung Hoch Tief Schluss Volumen 12/28/2014 8:00:00 -> 62.13 62.67 62.13 62.27 3206
28.12.2014 9:00:00 PM -> 62.27 62.42 62.14 62.39 1620
28.12.2014 10:00:00 -> 62.4 62.41 62.16 62.21 1275
12/28/2014 11:00:00 PM -> 62.21 62.32 61.96 62.19 2791
12/29/2014 12:00:00 -> 62.17 62.25 62.08 62.23 1233
12/29/2014 1:00:00 -> 62.23 62.41 62.21 62.31 1186
12/29/2014 2:00: 00.00 -> 62,32 62,32 62,07 62,21 1446
12/29/2014 3:00:00 AM -> 62,22 62,35 62,17 62,28 1335

ich jetzt einen höheren Zeitrahmen (täglich) aus der obigen stündlichen Probe erzeugen will .

beginne ich mit off:

ohlc 
|> Frame.rows 
|> Series.resampleEquiv (fun d -> d.Date) 

, die zurückgibt: Series<DateTime,Series<DateTime,ObjectSeries<string>>>.

ich erstellen mag einen neuen Datenrahmen enthält, die Spalten Date (Schlüssel), Open, High, Low, Close und Lautstärke. Geöffnet ist das 1. Öffnen in Reihe 1 der Serie. Hoch ist der Max High in der Serie. Low ist der Min Low in der Serie. Schließen ist das letzte Schließen der Serie. Volumen ist die Summe des Volumens in der Serie

So etwas wie:

ohlc 
|> Frame.rows 
|> Series.resampleEquiv (fun d -> d.Date) 
|> ?? 
|> ?? 

Anstatt zu versuchen, dies auf der Frame-Ebene zu tun Zeilen verwenden, wäre ich besser dran, dies versuchen zu tun mit Frame-Spalt verwenden?

UPDATE Hier der fertige Code ist:

ohlc 
|> Frame.rows 
|> Series.resampleEquiv (fun d -> d.Date) 
|> Series.mapValues (fun s -> 
    let temp = Frame.ofRows s 
    series ["Open" => Series.firstValue temp?Open 
      "High" => defaultArg (Stats.max temp?High) nan 
      "Low" => defaultArg (Stats.min temp?Low) nan 
      "Close" => Series.lastValue temp?Close 
      "Volume" => defaultArg (Some(Stats.sum temp?Volume)) nan ]) 
|> Frame.ofRows 

ich verwendet nicht in der Lage war: mir eine Fehlermeldung

"Volume" => defaultArg (Stats.sum temp?Volume) nan ]) 

wie dies gab: Dieser Ausdruck hat Typen float Option erwartet aber hier hat Typ float. Ich musste die Funktion Some() umbrechen. Nicht sicher, warum Stats.sum das erfordert, aber Stat.max und Stats.min nicht.

Antwort

1

Nachdem Sie resampleEquiv aufgerufen haben, erhalten Sie eine Reihe (die Chunks mit demselben Datum repräsentiert) der Serie (die Werte mit unterschiedlichen Zeiten aber demselben Datum darstellt) von Objektserien (die die verschiedenen Spalten des Originalframes darstellen).

Sie können über die Top-Level-Serie iterieren und jede Reihe von Objektserien (jeden Chunk) in einen Rahmen zurückdrehen. Dann können Sie die Aggregationen über den Rahmen tun und eine neue Zeile zurück:

source 
|> Series.resampleEquiv (fun d -> d.Date.Year) 
|> Series.mapValues (fun s -> 
    let temp = Frame.ofRows s 
    series [ "Open" => Series.firstValue temp?Open 
      "High" => defaultArg (Stats.max temp?High) nan ]) 
|> Frame.ofRows 

Ich tat es nur für Open und hoch, aber man kann :-) die Idee sehen. Der Aufruf der Frame.ofRows auf jedem der Chunks sollte auch ziemlich schnell sein, da Deedle weiß, dass alle Elemente im Chunk denselben Index haben.(Alternativ könnten Sie über die einzelnen Zeilen iterieren, aber das würde es länger machen).