1

我有以下数据:

let data = [(41609.00 , 10000., 3.822); (41609.00, 60000., 3.857); (41974.00 , 20000., 4.723 ); (41974.00, 30000., 3.22 ); (41974.00 , 4000., 4.655 ); (42339.00, 7000., 4.22 ); (42339.00 , 5000., 3.33)]

第一列 = OADate,第二列 = 交易量,第三列 = 价格。

我现在想按日期分组,对交易量求和并计算加权平均价格。这是我到目前为止所拥有的:

let aggr data = 
    data
    //Multiply second and third column element by element
    |> Seq.map (fun (a, b, c) -> (a, b, b * c))
    //Group by first column
    |> Seq.groupBy fst
    //Sum column 2 & 3 based on group of column 1
    |> Seq.map (fun (d, e, f) -> (d, e |> Seq.sum, f |> Seq.sum)) 
    //take the sum and grouped column 1 & 2 and compute weighted average of the third
    |> Seq.map (fun (g, h, i) -> (g, h, i/h)) 

我得到了元组长度不同的类型不匹配。我以前使用过类似的语法没有问题。谁能指出我正确的方向?

更新:

如果有人感兴趣,解决方案是:感谢 Tomas 和 Leaf

let aggr data = 
data
|> Seq.map (fun (a, b, c) -> (a, b, b * c))
|> Seq.groupBy (fun (a, b, c) -> a)
|> Seq.map (fun (key, group) -> group |> Seq.reduce (fun (a, b, c) (x, y, z) -> a, b+y , c+z))
|> Seq.map (fun (g, h, i) -> (g, h, i/h)) 
4

1 回答 1

4

代码中的第一个问题是您调用Seq.groupBywithfst作为参数。这不起作用,因为fst它是一个返回二元素元组的第一个元素的函数,但您的输入是三元素元组。遗憾的是,该函数不适用于任何元组。您需要编写一个从三个值中选择第一个值的 lambda:

(...)
|> Seq.groupBy (fun (a, b, c) -> a)

下一个问题是下一步的映射。分组生成一个包含键(时间)作为第一个元素的元组列表和一个包含原始输入序列中的元素列表的组(在您的情况下为三元素元组)。要将键与组中所有第二个组件的总和一起返回,您可以编写:

(...)
|> Seq.map (fun (key, group) -> key, group |> Seq.sumBy (fun (_, v, _) -> v))

我不完全确定你想对第二列和第三列做什么,但这应该让你知道如何继续。

于 2013-10-07T14:57:04.850 回答