如何累积(扫描)Deedle数据帧值

时间:2016-03-07 09:27:06

标签: f# deedle

我将一系列记录加载到deedle数据框(来自数据库表)。是否可以累积(例如累加)值,并获取数据帧?例如,有Seri​​es.scanValues但没有Frame.scanValues。有Frame.map,但它没有做我预期的事情,它保留了所有的值。

#if INTERACTIVE
#r @"Fsharp.Charting"
#load @"..\..\Deedle.fsx"
#endif

open FSharp.Charting
open FSharp.Charting.ChartTypes
open Deedle

type SeriesX = {
    DataDate:DateTime
    Series1:float
    Series2:float
    Series3:float
}

let rnd = new System.Random()
rnd.NextDouble() - 0.5

let data = 
    [for i in [100..-1..1] -> 
                        {SeriesX.DataDate = DateTime.Now.AddDays(float -i)
                         SeriesX.Series1 = rnd.NextDouble() - 0.5
                         SeriesX.Series2 = rnd.NextDouble() - 0.5
                         SeriesX.Series3 = rnd.NextDouble() - 0.5
                        }
    ]

# now comes the deedle frame:
let df = data |> Frame.ofRecords
let df = df.IndexRows<DateTime>("DataDate")
df.["Series1"] |> Chart.Line
df.["Series1"].ScanValues((fun acc x -> acc + x),0.0) |> Chart.Line

let df' = df |> Frame.mapValues (Seq.scan (fun acc x -> acc + x) 0.0) 
df'.["Series1"] |> Chart.Line

最后两行只是给我回原始值,而我希望得到累积值,如df。[&#34; Series1&#34;] .Sceel1,Series2和Series3的扫描值。

2 个答案:

答案 0 :(得分:1)

  

对于过滤和投影,系列提供了Where和Select方法   以及相应的Series.map和Series.filter函数(有   如果你只想转换,还有Seri​​es.mapValues和Series.mapKeys   一方面)。

所以你只需将你的功能应用到每个系列:

let allSum = 
    df.Columns
    |> Series.mapValues(Series.scanValues(fun acc v -> acc + (v :?> float)) 0.0)
    |> Frame.ofColumns

并使用Frame.ofColumns将结果转换为Frame。

修改

如果只需要选择数字列,可以使用Frame.getNumericCols:

let allSum = 
    df
    |> Frame.getNumericCols
    |> Series.mapValues(Series.scanValues (+) 0.0)
    |> Frame.ofColumns

没有明确的类型转换代码变得更加美观:)

答案 1 :(得分:1)

有一个Series.scanValues功能。您可以从数据框中的每一列获取一系列文字,如下所示:frame$column,它会为您提供Series

如果您需要一次所有列进行扫描,您可以先将每一行映射到一个值(例如,一个元组),然后将Series.scanValues应用于该新列。