Deedle,F#和Frame.map问题

时间:2019-02-26 09:28:32

标签: f# deedle

我很容易理解 Series.map 时,在理解 Frame.map (甚至还有其他)的签名时遇到了问题。

下面是一个简单的示例:

let ts1 = 
  series
   [ ("A", "A1", "p1") => 0.5 
     ("A", "A1", "p2") => 2.
     ("A", "A2", "p3") => 2. 
     ("A", "A2", "p4") => 0.5 ]

let ts2 = 
  series
   [ ("A", "A1", "p1") => "A"
     ("A", "A1", "p2") => "B"
     ("A", "A2", "p3") => "C"
     ("A", "A2", "p4") => "D" ]

let F = ["ts1" =?> ts1 ; "ts2" =?> ts2] |> Frame.ofColumns

假设我要在ts1系列上应用功能,没有问题:

ts1 |> Series.map (fun _ v -> v * 2.)

按预期工作...

但是,如果我想使用,让我们举个例子:

let fun1 (a: float) (b: string) =
    match b with
    |"B" -> a ** 2.
    |"C" -> a ** 3.
    |_   -> 0.

在框架 F 上,我只是无法弄清楚。我尝试调用列。

我不介意提供帮助,因为我无法通过以前的帖子/ Deedle doc / etc弄清楚它...我只是被签名所困...

let F2 = F |> Frame.mapRows (fun k a -> (fun1 a.GetAs<float>("ts1") a.GetAs<string>("ts2")))

1 个答案:

答案 0 :(得分:2)

在MATLAB / R / Python中使用矢量化索引这种操作非常直观。

在Deedle中,Frame.mapRows将每一行都作为ObjectSeries。我的丑陋解决方案就是这样

F
|> Frame.mapRows(fun _ v -> 
  match string v.["ts2"] with
  | "B" -> v |> Series.map(fun k v -> if k = "ts1" then box((unbox v) * 2.) else v)
  | "C" -> v |> Series.map(fun k v -> if k = "ts1" then box((unbox v) * 3.) else v)
  | _ -> v |> Series.map(fun k v -> if k = "ts1" then box(0.) else v)
)
|> Frame.ofRows