你如何使用Seq。按F#中的函数求平均值,以平均一行中的数据,并按另一行中的数据分组?
我有两排,州和收入。有多行具有相同的状态,但我希望每个状态有一行。因此,我希望按州平均所有收入数据,这样我可以得到每个州的平均值,每个州只有一个值/行。这是我试图将收入行中的值按州进行平均的尝试。 我将序列分组如下: Seq.groupBy(有趣的行->行状态) 但是,当我尝试平均收入列中已按州分组的数据时(从上面): 序号平均值(乐趣行->收入行) 它给了我这个错误: 错误FS0001:应为支持运算符“+”的类型,但给定了函数类型。函数可能缺少参数你如何使用Seq。按F#中的函数求平均值,以平均一行中的数据,并按另一行中的数据分组?,f#,F#,我有两排,州和收入。有多行具有相同的状态,但我希望每个状态有一行。因此,我希望按州平均所有收入数据,这样我可以得到每个州的平均值,每个州只有一个值/行。这是我试图将收入行中的值按州进行平均的尝试。 我将序列分组如下: Seq.groupBy(有趣的行->行状态) 但是,当我尝试平均收入列中已按州分组的数据时(从上面): 序号平均值(乐趣行->收入行) 它给了我这个错误: 错误FS0001:应为支持运算符“+”的类型,但给定了函数类型。函数可能缺少参数 我做错了什么?如果您想传入函数,您需要,而不
我做错了什么?如果您想传入函数,您需要,而不是
Seq.average
接受一个数字序列,而Seq.averageBy
接受一个函数和一个类型为T的事物序列(该函数应该是一个接受类型为T的事物并返回数字的函数)
另外,如果您首先使用Seq.groupBy
,请注意它返回一个元组序列,其中元组的第一个元素是键,第二个元素是具有该键的值序列。(在类型签名中,这由类型seq>
表示)。所以你想要的有点复杂,我会带你看一下:
rows |>Seq.averageBy(fun row->row.Income)
Seq.groupBy
,它返回一个元组序列。如果您执行了rows |>Seq.groupBy(fun row->row.State)|>Seq.averageBy(fun row->row.Income)
,那么您会收到一个错误,说明元组没有名为Income
的属性。因为Seq.groupBy
调用已将您的数据转换为如下内容:
seq {
(TX, seq { row1, row4, row7 })
(CA, seq { row2, row5, row8 })
(NY, seq { row3, row6, row9 })
}
rows
|> Seq.groupBy (fun row -> row.State)
|> Seq.map (fun (state, groupedRows) ->
let averageIncome = groupedRows |> Seq.averageBy (fun row -> row.Income)
(state, averageIncome))
seq {
(TX, 12345.0)
(CA, 34567.0)
(NY, 23456.0)
}
Seq.groupBy
生成的序列,并以保留键但转换值序列的方式对其进行转换。每当你想“我想保持这个序列,但把它的内容变成其他东西”,你就会想要Seq.map
接受一个函数,该函数接受一个类型为T的项(不管T可能是什么),但我们可以使用(查找该页面上的addOneToTuple
示例)使其更简单:因为我们知道我们映射的“外部”序列是一个(键,值)
的元组,所以我们可以编写该函数来接受(key,values)
tuple:fun(key,values)->key,(values |>Seq.averageBy…)
就是你想要的seq {
(TX, seq { row1, row4, row7 })
(CA, seq { row2, row5, row8 })
(NY, seq { row3, row6, row9 })
}
rows
|> Seq.groupBy (fun row -> row.State)
|> Seq.map (fun (state, groupedRows) ->
let averageIncome = groupedRows |> Seq.averageBy (fun row -> row.Income)
(state, averageIncome))
Seq.map
步骤中,我必须确保返回(state,averageIncome)
;如果我刚刚返回了groupedRows |>Seq.averageBy(fun row->row.Income)的结果
,那么我将把一个元组映射成一个值,你将得到一个平均收入的序列,而该序列不再附带州
我希望这能帮助您了解如何在F#中解决类似问题的过程。有,而且一开始可能会有点混乱。但无论您是初学者还是有经验的F#开发人员,基本方法都是一样的:您首先要说“我拥有什么样的数据,以及我完成后想要拥有什么样的数据?”然后,您寻找一个具有正确“形状”的函数,将类型a的数据转换为类型B的数据;如果没有单一的函数,您可以将多个函数(如构建块)组合在一起,以获得所需的整体函数。(例如,我们如何组合
Seq.map
和Seq.averageBy
).如果你想传入一个函数,你想要,而不是。Seq.average
接受一个数字序列,而Seq.averageBy
接受一个函数和一个类型为T的序列(函数应该是一个接受类型为T的东西并返回一个数字的函数)
另外,如果您首先使用Seq.groupBy
,请注意它返回一个元组序列,其中元组的第一个元素是键,第二个元素是具有该键的值序列。(在类型签名中,这由类型Seq>
表示).所以你想要的东西有点复杂,我会带你走过去:
rows |>Seq.averageBy(fun row->row.Income)
Seq.groupBy
,它返回一系列元组。如果调用了rows |>Seq.groupBy(fun row->row.State)|>Seq.averageBy(fun row->row.Income)
,则会出现一个错误,指出元组没有名为Income
的属性。因为Seq.groupBy
调用已将您的数据转换为如下内容:
seq {
(TX, seq { row1, row4, row7 })
(CA, seq { row2, row5, row8 })
(NY, seq { row3, row6, row9 })
}
rows
|> Seq.groupBy (fun row -> row.State)
|> Seq.map (fun (state, groupedRows) ->
let averageIncome = groupedRows |> Seq.averageBy (fun row -> row.Income)
(state, averageIncome))
seq {
(TX, 12345.0)
(CA, 34567.0)
(NY, 23456.0)
}
Seq.groupBy
生成的序列,并以一种保留键但转换值序列的方式对其进行转换。每当您认为“我想保留此序列,但将其内容转换为其他内容”时,您都需要Seq.map
接受一个函数,该函数接受一个类型为T的项(不管T可能是什么),但我们可以使用(查找该页面上的addOneToTuple
示例)使其更简单:因为我们知道我们映射的“外部”序列是一个(键,值)
的元组