2016-09-05 5 views
0

私は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 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) 
) 

と私は

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) 

私は一種二回使用して、必要な出力を取得し、逆転することができました

(29946 29945,-10.010943) 
(29920 29919,-9.658904) 
(10022 10021,-7.207875) 

を与えます。しかし、よりクリーンな方法で可能と考えています。任意の提案をいただければ幸いです。

+0

はすでにIDでソートされていますか? –

+0

いいえ、そうではありません。この例では申し訳ありませんが、そのように見えます。 – Laeeq

+0

スピードアップのために 'groupByKey'ではなく' reduceByKey'を使用してください。 'groupByKey'のためのドキュメントは"注:この操作は非常に高価かもしれません。各キーに対して集計(合計や平均など)を実行するためにグループ化する場合は、PairRDDFunctions.aggregateByKeyまたはPairRDDFunctions.reduceByKeyを使用しますパフォーマンスははるかに優れています。 –

答えて

1

それだけで、後に最大を取るために、最大ではなく、値のリストを維持しておそらくより効率的なバージョン。

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)) 
+0

これはより効率的でした。 – Laeeq

1
idAndScore.groupBy(_._1).mapValues(_.max).map(_._2).toList.sortBy(- _._2) 

または

idAndScore.groupBy(_._1).mapValues(_.max).map(_._2).toList.sortBy { case (k, v) => -v } 
+0

これはうまくいきます。 sortBy( - _._ 2)について説明できますか?私には、あなたは - を乗じているようです。 – Laeeq

+1

私は恥知らずに情報をコピーしましたhttp://stackoverflow.com/a/7803042/1879175 –

+1

@ user3771345私たちは数値でソートする必要がありますので、希望の順序を得るためにそれらを否定することができます。 HTH。 –

関連する問題