scala中每个组的最大值
我有一个id和分数数组,我想找到每个id的最高分数scala中每个组的最大值,scala,sorting,grouping,Scala,Sorting,Grouping,我有一个id和分数数组,我想找到每个id的最高分数 val idAndScore = Array( ("10022 10021", -6.1825), ("10022 10021", -6.477912), ("10022 10021", -7.207875), ("10022 10021", -6.251606), ("10022 10021", -6.343815), ("10022 10021", -6.62864), ("29920
val idAndScore = Array(
("10022 10021", -6.1825),
("10022 10021", -6.477912),
("10022 10021", -7.207875),
("10022 10021", -6.251606),
("10022 10021", -6.343815),
("10022 10021", -6.62864),
("29920 29919", -9.134842),
("29920 29919", -9.049803),
("29920 29919", -9.658904),
("29920 29919", -9.186851),
("29920 29919", -8.525129),
("29920 29919", -9.46663),
("29920 29919", -8.496784),
("29920 29919", -9.2584),
("29946 29945", -10.010943),
("29946 29945", -8.588902),
("29946 29945", -8.915169),
("29946 29945", -8.538752)
)
所需的输出为fallows
(10022 10021,-6.1825)
(29920 29919,-8.496784)
(29946 29945,-8.538752)
val top = idAndScore.groupBy { case (id, score) => id }
.flatMap(_._2.toList.sortBy { case (id, score) => score }.reverse)
我试过了
val top = idAndScore.groupBy { case (id, score) => id }
.flatMap(_._2.toList.sortBy { case (id, score) => score })
但它给了我
(29946 29945,-8.538752)
(29920 29919,-8.496784)
(10022 10021,-6.1825)
并添加反向作为休耕
(10022 10021,-6.1825)
(29920 29919,-8.496784)
(29946 29945,-8.538752)
val top = idAndScore.groupBy { case (id, score) => id }
.flatMap(_._2.toList.sortBy { case (id, score) => score }.reverse)
给予
我已经能够通过使用sort两次和reverse获得所需的输出。但我认为这可能是一种更干净的方式。如有任何建议,将不胜感激
idAndScore.groupBy(_._1).mapValues(_.max).map(_._2).toList.sortBy(- _._2)
或
或
可能是更高效的版本,因为它只是维护max,而不是值列表,以便以后获取max
idAndScore.foldLeft(Map[String, Double]() withDefaultValue Double.MinValue)
{ case (m, (k, v)) => m updated (k, v max m(k))}
.toSeq
.sortBy{-_._2}
// Seq[(String, Double)] = ArrayBuffer((10022 10021,-6.1825),
(29920 29919,-8.496784),
(29946 29945,-8.538752))
可能是更高效的版本,因为它只是维护max,而不是值列表,以便以后获取max
idAndScore.foldLeft(Map[String, Double]() withDefaultValue Double.MinValue)
{ case (m, (k, v)) => m updated (k, v max m(k))}
.toSeq
.sortBy{-_._2}
// Seq[(String, Double)] = ArrayBuffer((10022 10021,-6.1825),
(29920 29919,-8.496784),
(29946 29945,-8.538752))
输入是否已按id排序?不,不是。抱歉,在本例中,它们看起来是这样的。使用
reduceByKey
而不是groupByKey
可以加快速度。正如groupByKey
的文档所说,“注意:此操作可能非常昂贵。如果您分组是为了对每个键执行聚合(例如求和或平均),则使用pairddfunctions.aggregateByKey或pairddfunctions.reduceByKey将提供更好的性能。”@感谢ArchetyPalpaul,但在这种情况下,我们不执行并行spark rdd操作。这是串行scala。@user3771345,啊,好的!通常情况下,问题恰恰相反——人们发布的问题看起来像数组问题,但实际上他们使用的是Spark。但是,只跟踪最大值的折叠可能仍然比groupBy快,因为它为每个键建立了一个列表,其中您只对最大值感兴趣……输入是否已按id排序?不,不是。抱歉,在本例中,它们看起来是这样的。使用reduceByKey
而不是groupByKey
可以加快速度。正如groupByKey
的文档所说,“注意:此操作可能非常昂贵。如果您分组是为了对每个键执行聚合(例如求和或平均),则使用pairddfunctions.aggregateByKey或pairddfunctions.reduceByKey将提供更好的性能。”@感谢ArchetyPalpaul,但在这种情况下,我们不执行并行spark rdd操作。这是串行scala。@user3771345,啊,好的!通常情况下,问题恰恰相反——人们发布的问题看起来像数组问题,但实际上他们使用的是Spark。然而,只跟踪最大值的折叠可能仍然比groupBy快,因为它为每个关键点建立了一个列表,其中您只对最大值感兴趣……很好,这很有效。你能解释一下吗。对我来说,你似乎是在乘以-。@user3771345我们需要按数值排序,这样我们就可以对它们求反,以获得所需的顺序,我也更新了我的答案,嗯。很好,这很有效。你能解释一下吗。对我来说,你似乎是在乘以-。@user3771345我们需要按数值排序,这样我们就可以对它们求反,以获得所需的顺序,我也更新了我的答案,HTH。