基于行方式映射在Deedle中返回多个列/数据帧

时间:2015-07-23 17:08:22

标签: f# deedle

我想查看一帧中的每一行,并根据该行中的值为新帧构建多个列。

最终结果应该是一个框架,其中包含原始框架的列和新的列。

我有一个解决方案,但我想知道是否有更好的解决方案。我认为解释所需行为的最佳方式是一个例子。我使用Deedle's titanic data set

#r @"F:\aolney\research_projects\braintrust\code\QualtricsToR\packages\Deedle.1.2.3\lib\net40\Deedle.dll";;
#r @"F:\aolney\research_projects\braintrust\code\QualtricsToR\packages\FSharp.Charting.0.90.12\lib\net40\FSharp.Charting.dll";;
#r @"F:\aolney\research_projects\braintrust\code\QualtricsToR\packages\FSharp.Data.2.2.2\lib\net40\FSharp.Data.dll";;
open System
open FSharp.Data
open Deedle
open FSharp.Charting;;
#load @"F:\aolney\research_projects\braintrust\code\QualtricsToR\packages\FSharp.Charting.0.90.12\FSharp.Charting.fsx";;
#load @"F:\aolney\research_projects\braintrust\code\QualtricsToR\packages\Deedle.1.2.3\Deedle.fsx";;

let titanic = Frame.ReadCsv(@"C:\Users\aolne_000\Downloads\titanic.csv");;

这就是那个框架的样子:

val titanic : Frame<int,string> =

       PassengerId Survived Pclass Name                                                Sex    Age       SibSp Parch Ticket           Fare    Cabin Embarked 
0   -> 1           False    3      Braund, Mr. Owen Harris                             male   22        1     0     A/5 21171        7.25          S        
1   -> 2           True     1      Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38        1     0     PC 17599         71.2833 C85   C        

我的方法抓取每一行,使用一些选择逻辑,然后返回一个新的行值作为字典。然后我使用Deedle的扩展操作将此字典中的值转换为新列。

titanic?test <- titanic |> Frame.mapRowValues( fun x -> if x.GetAs<int>("Pclass") > 1 then dict ["A", 1; "B", 2] else dict ["A", 2 ; "B", 1] );;
titanic |> Frame.expandCols ["test"];;

这给出了以下新框架:

       PassengerId Survived Pclass Name                                                Sex    Age       SibSp Parch Ticket           Fare    Cabin Embarked test.A test.B 
0   -> 1           False    3      Braund, Mr. Owen Harris                             male   22        1     0     A/5 21171        7.25          S        1      2      
1   -> 2           True     1      Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38        1     0     PC 17599         71.2833 C85   C        2      1      

注意最后两列是 test.A和test.B 。实际上,这种方法创建了一个新帧(A和B),然后将帧连接到现有帧。

这对我的用例很好,但是其他人可能会感到困惑。它也强制前缀,例如&#34; test&#34;,在最后一列上并不是非常需要。

有没有办法将新值附加到上面代码中用x表示的行序列的末尾?

1 个答案:

答案 0 :(得分:1)

我发现你的方法非常优雅和聪明。因为新系列与原始框架共享索引,所以它也会非常快。所以,我认为你的解决方案实际上可能比替代选项更好(但我没有测量过这个)。

无论如何,另一个选项是从Frame.mapRowValues调用返回新行 - 因此对于每一行,我们将原始行与其他列一起返回。

titanic 
|> Frame.mapRowValues(fun x -> 
  let add =  
    if x.GetAs<int>("Pclass") > 1 then series ["A", box 1; "B", box 2] 
    else series ["A", box 2 ; "B", box 1]
  Series.merge x add)
|> Frame.ofRows