2016-03-07 6 views
1

Я загружаю последовательность записей в фрейм данных деды (из таблицы базы данных). Можно ли накапливать (например, суммарно) значения и возвращать кадр данных? Например, есть Series.scanValues, но нет Frame.scanValues. Существует FrameMap, но он не делал того, что я ожидал, он оставил все значения такими, какими они были.Как суммировать (сканировать) Значения фрейма данных Deedle

#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 

Последние две строки просто отдай мне исходные значения в то время как я хотел бы иметь накопленные значения, как и в ДФ. [ «Series1»]. Scanvalues ​​для Series1, Series2 и Series3.

+0

Извините, но не ясно, что вы хотите получить. –

+0

Если вы запустите следующий код: https://dotnetfiddle.net/kiPOy4, вы получите следующий результат: http://pastebin.com/30MBT9Y2. Как вы можете видеть - легко добавить столбцы в фрейм. –

+0

Вы также можете использовать стиль F #: 'df. [" Series1 "] |> Series.scanValues ​​((+)) 0.0' –

ответ

2

Для фильтрации и проекции, серия обеспечивает Где и выбрать методы и соответствующие функции 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, что для преобразования результата в рамку.

Edit:

Если вам нужно выбрать только Числовые столбцы, вы можете использовать Frame.getNumericCols:

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

без явного кода типа литой стали красивее :)

+0

Уже введен в эксплуатацию. Очень хорошо. Спасибо! Вам нужно будет изучить Deedle немного больше. – s952163

1

Функция Series.scanValues. Вы можете получить серию из каждого столбца в вашем фрейме данных: frame$column, в котором вы получите Series.

Если вам нужно все столбцы сразу для выполнения сканирования, вы можете сначала сопоставить каждую строку с одним значением (например, кортежем) и применить к нему новый экземпляр Series.scanValues.

+1

Я использую 'Series.scanValues' :) – s952163

Смежные вопросы