我正试图通过分析我的电费来学习一些F#和Deedle。
假设我有两个框架,一个包含我的电量:
let consumptionsByYear =
[ (2019, "Total", 500); (2019, "Day", 200); (2019, "Night", 300);
(2020, "Total", 600); (2020, "Day", 250); (2020, "Night", 350) ]
|> Frame.ofValues Total Day Night
2019 -> 500 200 300
2020 -> 600 250 350 另一项计划有两项定价结构不同的计划(一项固定费用或根据一天中的时间而变化的费用):
let prices =
[ ("Plan A", "Base fee", 50); ("Plan A", "Fixed price", 3); ("Plan A", "Day price", 0); ("Plan A", "Night price", 0);
("Plan B", "Base fee", 40); ("Plan B", "Fixed price", 0); ("Plan B", "Day price", 5); ("Plan B", "Night price", 2) ]
|> Frame.ofValues Base fee Fixed price Day price Night price
Plan A -> 50 3 0 0
Plan B -> 40 0 5 2 以前,我在SQL中使用交叉联接解决了这个问题,在Excel中使用了嵌套联接。为了复制这些输出,我找到了Frame.mapRows,但是使用它构建预期的输出似乎非常繁琐:
let costs = consumptionsByYear
|> Frame.mapRows (fun _year cols ->
["Total price" => (prices?``Base fee``
+ (prices?``Fixed price`` |> Series.mapValues ((*) (cols.GetAs<float>("Total"))))
+ (prices?``Day price`` |> Series.mapValues ((*) (cols.GetAs<float>("Day"))))
+ (prices?``Night price`` |> Series.mapValues ((*) (cols.GetAs<float>("Night"))))
)]
|> Frame.ofColumns)
|> Frame.unnest Total price
2019 Plan A -> 1550
Plan B -> 1640
2020 Plan A -> 1850
Plan B -> 1990 有没有更好的方法,甚至是小小的改进?
发布于 2021-08-31 04:33:59
我不是Deedle专家,但我认为这基本上是:
consumptionsByYear和周期昼夜价格,换言之:
consumptionsByYear periodicPrices basePrices
------------------- ------------------------ ---------------------------
| Day Night | | Plan A Plan B | | Plan A Plan B |
| 2019 -> 200 300 | * | Day -> 3 5 | + | Base fee -> 50 40 |
| 2020 -> 250 350 | | Night -> 3 2 | ---------------------------
------------------- ------------------------考虑到这种方法,我会这样做:
open Deedle
open Deedle.Math
let consumptionsByYear =
[ (2019, "Day", 200); (2019, "Night", 300)
(2020, "Day", 250); (2020, "Night", 350) ]
|> Frame.ofValues
let basePrices =
[ ("Plan A", "Base fee", 50)
("Plan B", "Base fee", 40) ]
|> Frame.ofValues
|> Frame.transpose
let periodicPrices =
[ ("Plan A", "Day", 3); ("Plan A", "Night", 3)
("Plan B", "Day", 5); ("Plan B", "Night", 2) ]
|> Frame.ofValues
|> Frame.transpose
// repeat the base prices for each year
let basePricesExpanded =
let row = basePrices.Rows.["Base fee"]
consumptionsByYear
|> Frame.mapRowValues (fun _ -> row)
|> Frame.ofRows
let result =
Matrix.dot(consumptionsByYear, periodicPrices) + basePricesExpanded
result.Print()产出如下:
Plan A Plan B
2019 -> 1550 1640
2020 -> 1850 1990为了简单起见,我做了一些修改:
consumptionsByYear Total列,因为它可以从其他两个派生出来。prices Day price改为Day,将Night price更改为Night,以使矩阵兼容。Fixed price列,因为它可以在Day和Night列中表示。更新:从Deedle 2.4.2开始,不再需要将年份映射到字符串。我已经相应地修改了我的解决方案。
https://stackoverflow.com/questions/68990397
复制相似问题