Soldalma
Soldalma

Reputation: 4758

What would be an example for Frame.mapCols?

I am trying to create examples for all the methods in Deedle, with mixed success. I was able to provide an example for Frame.filterColValues but not for Frame.mapCols. Stealing from one of Tomas Petricek's numerous writeups, I defined a DataFrame as follows:

open Deedle

let dates  = 
  [ DateTime(2013,1,1); 
    DateTime(2013,1,4); 
    DateTime(2013,1,8) ]

let values = [ 10.0; 20.0; 30.0 ]

let first = Series(dates, values)

/// Generate date range from 'first' with 'count' days
let dateRange (first:System.DateTime) count =
    seq {for i in 0..(count - 1) -> first.AddDays(float i)}

/// Generate 'count' number of random doubles
let rand count =
    let rnd = System.Random()
    seq {for i in 0..(count - 1) -> rnd.NextDouble()}

// A series with values for 10 days 
let second = Series(dateRange (DateTime(2013,1,1)) 10, rand 10)

// df1 has two columns
let df1 = Frame(["first"; "second"], [first; second])

Next I was able to provide an example for Frame.filterColValues:

let df2 = Frame.filterColValues (fun s -> (s.GetAtAs<double>(0) > 5.0)) df1
// df2 has only one column
Frame.toArray2D(df2)

But I could not (and I tried hard) create an example for Frame.map cols. The best I could come up with was:

let df3 = Frame.mapCols (fun k x -> x.GetAtAs<double>(0)) df1
error FS0001: The type 'double' is not compatible with the type 'ISeries<'a>'

What am I doing wrong? Can someone post an example? Or, even better, point to a place where there are examples for the Deedle methods?

Upvotes: 2

Views: 187

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243106

The Frame.mapCols function lets you transform a column series into another column series.

The most basic example is just to return the column series unchanged:

df1 
|> Frame.mapCols (fun k col -> col)

As Foggy Finder mentioned in a comment, you can fill all missing values in a column using this - the body of the lambda has to return a series:

df1 
|> Frame.mapCols (fun k v -> Series.fillMissingWith 0.0 v)

If you wanted, you could return a series with just a single element (this turns your frame into a frame with one row - containing data from the first row - and original number of columns):

df1 
|> Frame.mapCols (fun k col -> series [ 0 => col.GetAtAs<float>(0) ])

In your code snippet, it looks like you wanted just a series (with a single value for each column), which can be done by getting the columns and then using Series.map:

df1.Columns
|> Series.map (fun k col -> col.GetAtAs<float>(0))

Upvotes: 4

Related Questions