Frage

In einer früheren Anfrage ( Arbeiten mit heterogenen Daten in einer statischen Sprache getippt), fragte ich, wie F # Griffe Standardaufgaben in der Datenanalyse, wie eine nicht typisierte CSV-Datei zu manipulieren. Dynamische langauges zeichnen sich grundlegende Aufgaben wie

data = load('income.csv')
data.log_income = log(income)

In F #, der eleganteste Ansatz scheint das Fragezeichen (?) Operator zu sein. Leider gibt es in dem Prozess verlieren wir statische Typisierung und brauchen noch Anmerkungen hier eingeben und dort.

Eine der spannendsten Zukunft Merkmal F # sind Typ Providers . Mit minimalem Verlust an Typsicherheit könnte ein CSV-Typ-Provider-Typen zur Verfügung stellen, indem Sie die Datei dynamisch zu untersuchen.

Aber die Datenanalyse stoppt normalerweise nicht da. Wir verwandeln oft die Daten und neue Datensätze erstellen, über eine Pipeline von Operationen. Meine Frage ist, können Provider Hilfe Typ wenn wir meist Daten manipulieren? Zum Beispiel:

open CSV // Type provider
let data = CSV(file='income.csv') // Type provider magic (syntax?)
let log_income = log(data.income) // works!

Das funktioniert aber verpestet der globale Namensraum. Oft ist es natürlich, über das Hinzufügen einer Spalte zu denken, anstatt eine neue Variable zu schaffen. Gibt es irgendeine Art und Weise zu tun?

let data.logIncome = log(data.income) // won't work, sadly.

Do-Typ-Provider bieten einen Ausweg aus der Verwendung des (?) Operators, wenn das Ziel, neue Derivat oder aufgeräumte Datensätze schafft?

Vielleicht so etwas wie:

let newdata = colBind data {logIncome = log(data.income)}  // ugly, does it work?

Andere Ideen?

War es hilfreich?

Lösung

Die kurze Antwort ist nein, die lange Antwort ja ist (aber Sie würde nicht wie das Ergebnis). Der Schlüssel ist daran zu erinnern ist, dass F # ist eine statisch typisierte Sprache, Punkt .

Für den Code, den Sie zur Verfügung gestellt, welche Art hat newData? Wenn es nicht zum Zeitpunkt der Kompilierung festgenagelt werden kann, dann müssen Sie Casting zu / von Obj greifen.

// newdata MUST have a static type, even if obj
let newdata = colBind data {logIncome = log(data.income)}  

Stellen Sie sich vor colBind die folgenden sinature hat:

val colBind: Thingey<'a> -> 'b -> Thingey2<'a, 'b>

Das wäre für eine Art und Weise tatsächlich funktionieren, aber es wäre allgemein nicht funktionieren. Denn schließlich würden Sie eine Art benötigen, die zum Zeitpunkt der Kompilierung nicht existieren würden.

F # Typ-Providern können Sie auf statisch Typ Daten mit Ursprung außerhalb der Standard-Kompilierung-Umgebung. Allerdings sind die Typen noch statisch. Es gibt keine Möglichkeit, diese Typen zur Laufzeit dynamisch zu verändern *.

* Sie können das Objekt zur Laufzeit mit Spielereien ändern wie Dynamic. Allerdings, wenn Sie beginnen diesen Weg hinunter Sie verlieren alle Vorteile einer statisch typisierten Sprache wie Intellisense. (Was ist ein wesentlicher Grund für die Verwendung von F # an erster Stelle).

Konzeptionell, was Sie tun wollen, ist einfach. Der System.Data.DataTable Typ hat bereits den Begriff tabellarische Daten zu speichern, mit die Fähigkeit, dynamisch Spalten hinzufügen. Da aber die Typinformationen für zusätzliche Spalten bei der Kompilierung nicht bekannt sind, folgt daraus, dass in diesen Spalten gespeicherten Dingen müssen Obj behandelt und zur Laufzeit gegossen.

Andere Tipps

Alternativ können Sie ‚von‘ und ‚zu‘ Tabellen mit, mit der Tabellen erstellen die benötigten Spalten. Auf diese Weise haben Sie ein statisch typisierte Abfrage und Ergebnis Schema, dass der Typ-Anbieter arbeiten mit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top