You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

F#中使用Deedle做交叉连接计算电费的更优实现方法问询

核心优化思路

你原来的代码冗余主要来自手动调用Series.mapValues做数值运算,Deedle已经内置了Series和标量的数值运算符重载,可以直接省略这部分代码,简化后写法如下:

let costs = 
    consumptionsByYear
    |> Frame.mapRows (fun _ cons ->
        prices?``Base fee``
        + prices?``Fixed price`` * cons.GetAs<int>("Total")
        + prices?``Day price`` * cons.GetAs<int>("Day")
        + prices?``Night price`` * cons.GetAs<int>("Night")
    )
    |> Frame.unnest
    |> Frame.renameColumns (fun _ -> "Total price")

输出结果和你原来的实现完全一致。


可选的交叉连接实现(更贴近SQL使用习惯)

如果你更熟悉SQL的交叉连接逻辑,可以用临时常量键实现两个Frame的笛卡尔积,计算逻辑更直观,后续扩展筛选、分组逻辑也更方便:

// 为两个数据集添加临时常量键用于交叉连接
let consumptionsWithJoinKey = consumptionsByYear |> Frame.addCol "JoinKey" (Series.constValue consumptionsByYear.RowKeys 1)
let pricesWithJoinKey = prices |> Frame.addCol "JoinKey" (Series.constValue prices.RowKeys 1)

let costs = 
    consumptionsWithJoinKey.Join(pricesWithJoinKey, (fun a b -> a = b), JoinKind.Outer)
    |> Frame.mapRows (fun _ row ->
        row.GetAs<int>("Base fee")
        + row.GetAs<int>("Fixed price") * row.GetAs<int>("Total")
        + row.GetAs<int>("Day price") * row.GetAs<int>("Day")
        + row.GetAs<int>("Night price") * row.GetAs<int>("Night")
    )
    |> Frame.ofSeries
    |> Frame.renameColumns (fun _ -> "Total price")

其他可优化的细节点

  • 省去不必要的类型转换:你原始的两个数据集值都是int类型,不需要额外转成float计算,减少类型转换开销
  • 可将计算逻辑抽为独立函数:如果后续需要调整费用计算规则、或者新增更多计价维度,抽离后的函数复用性更强
  • 如果数据量较大,可以提前把电价的四个列转为Series<int>缓存,避免每次行计算时都重复取列,提升运行效率

内容的提问来源于stack exchange,提问作者Jani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 18:48:03