我有两排,国家和收入。有多行具有相同的状态,但我希望每个州有一行。因此,我希望按州平均所有的收入数据,这样我就可以得到每个州的平均值,每个州只有一个值/行。这是我在收入行中按State行求平均值的尝试。我把序列分组如下:
Seq.groupBy(趣味行-> row.State)
但是,当我试图对收入一栏中的数据进行平均时,这一栏已经按国家分类(从上面):
Seq.average(趣味行-> row.Income)
它给了我这个错误:
“error FS0001:期望一个类型支持操作符'+‘,但给定一个函数类型。您可能缺少一个函数的参数。”
我做错什么了?
发布于 2018-06-06 23:12:28
如果要传递函数,则需要Seq.averageBy,而不是Seq.average。Seq.average接受一个数字序列,而Seq.averageBy则接受一个函数和一个T类型的事物序列(这个函数应该是一个T类型的函数,并返回一个数字)。
另外,如果您首先使用Seq.groupBy,请注意它返回一个元组序列,其中元组的第一个元素是键,第二个元素是具有该键的值序列。(在类型签名中,这由类型seq<'Key * seq<'T>>表示)。所以你想要的是有点复杂,我会告诉你的:
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 }) }Seq.groupBy生成的序列,并以保留键但转换值序列的方式对其进行转换。每当您认为“我希望保留此序列,但将其内容转换为其他内容”时,您就需要Seq.map。Seq.map接受一个T类型的函数(不管T是什么),但是我们可以使用函数参数的破坏 (查找页面上的addOneToTuple示例)来简化它:因为我们知道我们正在映射的“外部”序列是(key, values)的一个元组,所以我们可以编写函数来获取(key, values)元组:fun (key, values) -> key, (values |> Seq.averageBy ...)就是您想要的。这样就行了。注意,在最后的Seq.map步骤中,我必须确保返回一个(state, averageIncome)的元组;如果我刚刚返回了groupedRows |> Seq.averageBy (fun row -> row.Income)的结果,那么我就会将一个元组映射到单个值,您将得到一个不再附加状态的平均收入的集合。
我希望这能帮助您了解如何在F#中解决这样的问题。这里有在集合(如列表或序列)上工作的许多不同的函数,一开始它可能有点混乱。但是,无论您是初学者还是经验丰富的F#开发人员,基本的方法都是一样的:您首先要问:“我有什么样的数据,在我完成时我想拥有什么样的数据?”然后,寻找一个具有正确“形状”的函数,将A类型的数据转换为B类型的数据;如果没有单一的函数,则将几个函数组合在一起,比如构建块,以获得所需的整体功能。(例如,我们是如何将Seq.map和Seq.averageBy结合在一起的)。
https://stackoverflow.com/questions/50730616
复制相似问题