/ / f # deedle agregują wartości wierszy na podstawie klucza kolumny - f #, deedle

f # deedle agregują wartości wierszy na podstawie klucza kolumny - f #, deedle

mówię, że mam następujące Frame,

type Person =
{ Name:string; Age:int; Comp1:float; Comp2:float }

let peopleRecds =
[ { Name = "Joe"; Age = 51; Comp1=12.1; Comp2 =20.3 }
{ Name = "Tomas"; Age = 28; Comp1=1.1; Comp2 =29.3 }
{ Name = "Eve"; Age = 2; Comp1=2.1; Comp2 =40.3 }
{ Name = "Suzanne"; Age = 15; Comp1=12.4; Comp2 =26.3} ]
let peopleList = Frame.ofRecords peopleRecds

To, co chciałbym zrobić, to zsumować Comp1 i Comp2 kolumny w nowej kolumnie dla peopleListi n dla Comp(n) jest niezdecydowany w tej chwili, więc nie mogę po prostu wiedzieć tylko suma dwie kolumny, nie może być Comp3, Comp4, więc musimy opierać się na wyrażeniu regularnym, coś takiego jak klucz prowadzi Comp.

Wygląda na to, że powinienem to zrobić mapRowValues w każdym rzędzie

   peopleList?TotalComp <- peopleList |>Frame.mapRowValues(
fun row ->
(do something to sum up)
)

Jednak nie jestem pewien, jak operować na poziomie wiersza tutaj.

Odpowiedzi:

2 dla odpowiedzi № 1

Jeśli planowane jest zwiększenie liczby "Comp", lepiej byłoby umieścić je w tablicy:

type nPerson =  { Name:string; Age:int; Comp:float[] }

let npeopleRecds =
[ { Name = "Joe"; Age = 51; Comp = [| 12.1; 20.3 |] }
{ Name = "Tomas"; Age = 28; Comp = [| 1.1; 29.3  |] }
{ Name = "Eve"; Age = 2; Comp = [| 2.1; 40.3  |] }
{ Name = "Suzanne"; Age = 15; Comp = [|12.4; 26.3 |] } ]

Następnie możesz łatwo dodać kolumnę z sumą:

let npeopleList = Frame.ofRecords npeopleRecds

npeopleList.Format() |> printfn "%s"

let sumseries = npeopleList.GetColumn<float []>("Comp") |> Series.mapValues(fun x -> x |> Array.sum)

npeopleList?TotalComp <- sumseries

npeopleList.Format() |> printfn "%s"

Wydrukować:

     Name    Age Comp
0 -> Joe     51  System.Double[]
1 -> Tomas   28  System.Double[]
2 -> Eve     2   System.Double[]
3 -> Suzanne 15  System.Double[]

Name    Age Comp            TotalComp
0 -> Joe     51  System.Double[] 32,4
1 -> Tomas   28  System.Double[] 30,4
2 -> Eve     2   System.Double[] 42,4
3 -> Suzanne 15  System.Double[] 38,7

Edytować:

Jeśli zmiana pól w rekordzie Osoby jest niedopuszczalna - możesz użyć filtrów:

let allSum =
peopleList.Columns
|> Series.filter(fun k _ -> k.StartsWith("Comp"))
|> Frame.ofColumns
|> Frame.rows
|> Series.mapValues(Series.foldValues(fun acc v -> acc + (v :?> float)) 0.0)


peopleList?TotalComp <- allSum

peopleList.Format() |> printfn "%s"

Wydrukować:

     Name    Age Comp1 Comp2 TotalComp
0 -> Joe     51  12,1  20,3  32,4
1 -> Tomas   28  1,1   29,3  30,4
2 -> Eve     2   2,1   40,3  42,4
3 -> Suzanne 15  12,4  26,3  38,7