2010-12-21 72 views
9

前一個問題(Working with heterogenous data in a statically typed language),我問了一下F#如何處理數據分析標準的任務,如操縱非類型化的CSV文件。動態語言擅長於基本任務,如F#類型提供程序和數據處理

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

在F#中,最優雅的方法似乎是問號(?)運算符。不幸的是,在這個過程中,我們失去了靜態類型,並且仍然需要類型註釋。

一個F#中最令人興奮的未來功能是Type Providers。以最小的類型安全性損失,CSV類型提供者可以通過動態檢查文件來提供類型。

但數據分析通常不會停在那裏。我們經常通過一系列的操作來轉換數據並創建新的數據集。我的問題是,如果我們主要操縱數據,類型提供程序可以提供幫助嗎?例如:

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

這可行,但會污染全局命名空間。考慮添加一列通常更自然,而不是創建一個新變量。有什麼方法可以做?

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

進行類型供應商提供使用時,我們的目標是創造新的衍生物或清理後的數據集(?)運算符逃生?

也許是這樣的:

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

其他的想法?

回答

6

簡短的回答是否定的,長的答案是肯定的(但你不喜歡的結果)。關鍵要記住的是,F#是一種靜態類型語言,句號

對於您提供的代碼,newData有哪些類型?如果它不能在編譯時被固定下來,那麼你需要求助於Obj的鑄造。

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

想象colBind具有以下sinature:

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

這實際上爲一個工作方式,但它不會普遍地工作。因爲最終你需要一個在編譯時不存在的類型。

F#類型提供程序允許您將靜態類型數據源自標準編譯時環境的外部。但是,類型仍然是靜態的。在運行時*無法動態改變這些類型。

*您可以在運行時使用模糊修改對象,如 DynamicObject。但是,一旦 開始沿着這條路走下去,您將失去靜態類型 語言的所有優勢,如Intellisense。 (這是首先使用F#的主要原因。)

從概念上講,你想要做的是直截了當。System.Data.DataTable類型已經具有存儲表格數據的概念,並具有動態添加列的功能。但由於添加列的類型信息在編譯時並不知道,因此存儲在這些列中的內容必須被視爲Obj並在運行時進行轉換。

0

或者,您可以創建'from'和'to'表格,其中表格具有所需的列。這樣,您就有了一個類型提供程序使用的靜態類型查詢和結果模式。

相關問題