f# deedle 基于列键聚合行值

标签 f# deedle

假设我有以下框架

type Person = 
   { Name:string; Age:int; Comp1:float; Comp2:float }

let peopleRecds = 
    [ { Name = "Joe"; Age = 51; Comp1=12.1; Comp2 =20.3 }
      { Name = "Tomas"; Age = 28; Comp1=1.1; Comp2 =29.3 }
      { Name = "Eve"; Age = 2; Comp1=2.1; Comp2 =40.3 }
      { Name = "Suzanne"; Age = 15; Comp1=12.4; Comp2 =26.3} ]
let peopleList = Frame.ofRecords peopleRecds

我想要做的是将 Comp1Comp2 列求和到 peopleList 的新列中,并且 n for Comp(n) 目前尚未确定,所以我不能只知道两列之和,可能有 Comp3Comp4,所以必须基于正则表达式,比如 key 是用 Comp 开头的。

看来我应该做的是在每一行上mapRowValues

   peopleList?TotalComp <- peopleList |>Frame.mapRowValues(
                                          fun row -> 
                                              (do something to sum up)
                                         )

但是我不确定如何在此处进行行级别操作。

最佳答案

如果计划增加 'Comp' 的数量,最好将它们放入数组中:

type nPerson =  { Name:string; Age:int; Comp:float[] }

let npeopleRecds = 
    [ { Name = "Joe"; Age = 51; Comp = [| 12.1; 20.3 |] }
      { Name = "Tomas"; Age = 28; Comp = [| 1.1; 29.3  |] }
      { Name = "Eve"; Age = 2; Comp = [| 2.1; 40.3  |] }
      { Name = "Suzanne"; Age = 15; Comp = [|12.4; 26.3 |] } ]

然后您可以轻松添加一列,其总和为:

let npeopleList = Frame.ofRecords npeopleRecds

npeopleList.Format() |> printfn "%s"

let sumseries = npeopleList.GetColumn<float []>("Comp") |> Series.mapValues(fun x -> x |> Array.sum)

npeopleList?TotalComp <- sumseries

npeopleList.Format() |> printfn "%s"

打印:

     Name    Age Comp
0 -> Joe     51  System.Double[]
1 -> Tomas   28  System.Double[]
2 -> Eve     2   System.Double[]
3 -> Suzanne 15  System.Double[]

     Name    Age Comp            TotalComp
0 -> Joe     51  System.Double[] 32,4
1 -> Tomas   28  System.Double[] 30,4
2 -> Eve     2   System.Double[] 42,4
3 -> Suzanne 15  System.Double[] 38,7

编辑:

如果人员记录中的字段更改 Not Acceptable - 您可以使用过滤器:

let allSum = 
    peopleList.Columns
    |> Series.filter(fun k _ -> k.StartsWith("Comp"))
    |> Frame.ofColumns
    |> Frame.rows
    |> Series.mapValues(Series.foldValues(fun acc v -> acc + (v :?> float)) 0.0)


peopleList?TotalComp <- allSum

peopleList.Format() |> printfn "%s"

打印:

     Name    Age Comp1 Comp2 TotalComp
0 -> Joe     51  12,1  20,3  32,4
1 -> Tomas   28  1,1   29,3  30,4
2 -> Eve     2   2,1   40,3  42,4
3 -> Suzanne 15  12,4  26,3  38,7

关于f# deedle 基于列键聚合行值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35824929/

相关文章:

f# - 匹配一个数字,如果它是 2 的倍数

powershell - 为什么从 PowerShell 调用 F# 代码时收到 MissingMethodException?

F# Deedle 返回奇怪的输出 <fun :it@156-43>

f# - Series.hasNot 中有错误吗?

f# - 部分延迟计算构建器

F# 累积随机数序列

f# - 我如何在 F# 中编写经典的高/低游戏?

C# - 将 R 数据帧转换为 Deedle.Frame

filter - 在 F# 中处理 Deedle 时间序列中的缺失值 (2)

f# - 为什么 Frame.tryValues 在这个简单的例子中会失败?