Get a column by name as array from CsvFile.Load (or create dictionary of arrays from csv)

StackOverflow https://stackoverflow.com//questions/21030203

  •  21-12-2019
  •  | 
  •  

Question

I have the following code to load a csv. What is the best way to get a column from "msft" (preferably by name) as an array? Or should I be loading the data in a different way to do this?

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

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

Edit: Alternatively, what would be an efficient way to import a csv into a dictionary of arrays keyed by column name? If I should really be creating a new question for this, please let me know. Not yet familiar with all stackoverflow standards.

Was it helpful?

Solution

When you say you want to column "by name" it's not clear if you mean "someone passes me the column name as a string" or "I use the column name in my code." Type providers are perfect for the latter case, but do not really help with the former.

For the latter case, you could use this:

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

If the former, you might want to consider reading in the data some other way, perhaps to a dictionary keyed by column names.

The whole point of type providers is to make all of this strongly typed and code-focused, and to move away from passing column names as strings which might or might not be valid.

OTHER TIPS

Building on Latkin's answer, this seems like the more functional or F# way of doing what you want.

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

I hope that this helps.

I went through this example as well. Something like the following should do it.

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

Here I am piping the msft.Data list of msft data records and folding it down to a list of one item from that list. Please check the documentation for all functions mentioned. I have not run this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top