2014-01-09 36 views
1

我有以下代碼來加載csv。從「msft」(最好是通過名稱)獲得一列作爲數組的最佳方式是什麼?或者我應該以不同的方式加載數據來做到這一點?從CsvFile.Load(或從csv創建數組字典)按名稱獲取列

#r "FSharp.Data.dll" 
open FSharp.Data.Csv 

let msft = CsvFile.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT").Cache() 

編輯:或者,將csv導入按列名鍵控的數組字典中的一種有效方法是什麼?如果我真的應該爲此創建一個新問題,請讓我知道。還不熟悉所有的stackoverflow標準。

回答

0

當你說你想要「按名稱」列時,不清楚你的意思是「有人把我的列名作爲字符串傳給我」或「我在我的代碼中使用列名」。類型提供者對於後一種情況是完美的,但對前者並沒有真正的幫助。

對於後一種情況,你可以這樣做:

let closes = [| yield! msft.Data |> Seq.map (fun x -> x.Close) |] 

如果是前者,你可能要考慮在數據讀取一些其他的方式,也許是通過列名鍵控字典。

整個類型提供程序的重點是使所有這些強類型和代碼爲重點的,並且不再將列名傳遞爲可能有效或無效的字符串。

+0

對不起,不清楚。我真正想要的是一個由列名鍵控的數組字典。我想過這樣做,但我不確定這是否是一種「正確」的表示數據的方式,但是您提到的這一事實使我更加確定它。我仍然不確定如何有效地將數據從csv(或sql)導入到數組字典中。有什麼建議麼? – dood

+0

您必須先創建一個'ResizeArrays'字典(又名'S.C.G.List '),因爲您將隨時隨地構建它。讀取/解析文件的第一行以填充鍵,然後分割文件的每一行,將數據添加到每個適當鍵下的'ResizeArray'。可能已經有一個圖書館在那裏做這樣的事情。 – latkin

1

我也經歷了this example。像下面這樣的東西應該這樣做。

let data = 
    msft.Data 
    |> List.fold (fun acc row -> row.Date :: acc) List.Empty<DateTime> 

在這裏,我管道msft數據記錄的msft.Data列表,並將其摺疊到列表中的一個項目列表。請檢查文檔中提到的所有功能。我沒有運行這個。

2

建立在Latkin的答案上,這看起來像是更多的功能或F#的做你想做的方式。

let getVector columnAccessor msft = 
    [| yield! msft.Data |> Seq.map columnAccessor |] 

(* Now we can get the column all at once *) 
let closes = getVector (fun x -> x.Close) msft 

(* Or we can create an accessor and pipe our data to it. *) 
let getCloses = getVector (fun x -> x.Close)  
let closes = msft |> getCloses 

我希望這會有所幫助。