1

我正在尝试使用 Deedle 进行一些基于行的计算。但是大多数示例都是基于列的。例如我有这个简单的结构:

let tt = Series.ofObservations[ 1=>10.0; 3=>20.0;5=> 30.0 ]
let tt2 = Series.ofObservations[1=> 10.0; 3=> Double.NaN; 6=>30.0 ]
let f1 = frame ["cola" => tt; "colb"=>tt2]

 val f1 : Frame<int,string> =
          cola      colb      
      1 -> 10        10        
      3 -> 20        <missing> 
      5 -> 30        <missing> 
      6 -> <missing> 30  

我想计算可乐和可乐的平均值。如果我做

f1.Rows |> Series.mapValues(fun r -> (r.GetAs<float>("cola") + r.GetAs<float>("colb") )/2.0)
val it : Series<int,float> =
     1 -> 10        
     3 -> <missing> 
     5 -> <missing> 
     6 -> <missing>  

我知道我可以匹配每一列来处理平均值,但是如果有很多列,这将不切实际。

f1.Rows 返回的每一行都是一个 ObjectSeries 可以将其转换为浮点系列并将 stats.mean 应用于一行吗?

谢谢卡比

更新:

我想我可能已经找到了一种方法来做到这一点(参考:https ://github.com/BlueMountainCapital/Deedle/issues/100 ):

折叠操作:

 f1.Rows |> Series.mapValues(fun v -> v.As<float>() |> Series.foldValues (fun acc elem -> elem + acc) 0.0 ) 

意思是(它正确地跳过了缺失值):

 f1.Rows |> Series.mapValues(fun v -> v.As<float>() |> Stats.mean )

数数:

 f1.Rows |> Series.mapValues(fun v -> v.As<float>() |> Stats.count )

如果有不同的方法,请告诉我。希望这对像我这样的新人有用。

4

1 回答 1

4

您使用的方法f1.Rows,将每一行转换为数字系列,然后应用Stats函数正是我要建议的答案,所以我认为这种方法非常有意义。

我能想到的另一个选择是将框架转换为非规范化表示,然后按colacolb值对行进行分组(因此,您将所有数据作为行,但按其他属性分组):

let byCol = 
  f1
  |> Frame.stack
  |> Frame.groupRowsByString "Column";;

这给了你:

          Row Column Value 
cola 0 -> 1   cola   10    
     2 -> 3   cola   20    
     3 -> 5   cola   30    
colb 1 -> 1   colb   10    
     4 -> 6   colb   30    

现在,您可以使用处理分层索引的函数来进行计算。例如,要计算Value两组的平均值,您可以编写:

byCol?Value |> Stats.levelMean fst

我不确定目前我会推荐哪种方法 - 它可能取决于您需要对数据执行的其他操作。但是最好记住另一种..

于 2014-08-17T08:50:27.877 回答