【问题标题】:How to cumulate (scan) Deedle data frame values如何累积(扫描)Deedle 数据帧值
【发布时间】:2016-03-07 09:27:06
【问题描述】:

我正在将一系列记录加载到 deedle 数据框中(来自数据库表)。是否可以累积(例如累积总和)值,并取回数据框?例如,有 Series.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.["Series1"].Scanvalues 中的累积值,用于 Series1、Series2 和 Series3。

【问题讨论】:

  • 对不起,不清楚你想得到什么。
  • 如果您运行以下代码:dotnetfiddle.net/kiPOy4,您将得到以下结果:pastebin.com/30MBT9Y2。如您所见 - 可以轻松地在框架中添加列。
  • 你也可以使用F#样式:df.["Series1"] |&gt; Series.scanValues((+)) 0.0
  • @FoggyFinder 感谢您对此进行调查。是的,这有点令人费解,所以让我澄清一下:我想累积所有三个系列。在伪代码中 df |> Frame.scanValue((+)) 0.0 这将累积 Frame 中的每个系列。对于您的代码,对于系列 1、系列 2 和系列 3,它将从 1 变为 55。
  • 嗯,那你可以这样做:pastebin.com/LEG8vT1d

标签: f# deedle


【解决方案1】:

对于过滤和投影,series 提供了 Where 和 Select 方法 以及对应的 Series.map 和 Series.filter 函数(有 如果您只想转换,还有 Series.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

没有显式类型转换的代码变得更漂亮:)

【讨论】:

  • 已经投产。非常好。谢谢你!需要进一步探索 Deedle。
【解决方案2】:

有一个Series.scanValues 函数。您可以像这样从数据框中的每一列中获取一个系列:frame$column,这将为您提供Series

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

【讨论】:

  • 我实际上在使用Series.scanValues :)
猜你喜欢
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多