【问题标题】:SortByValue for a RDD of tuples元组 RDD 的 SortByValue
【发布时间】:2015-09-09 18:02:22
【问题描述】:

最近我被要求(在课堂作业中)找出 RDD 中出现频率最高的 10 个单词。我提交了一个可行的解决方案,看起来像

wordsRdd
  .map(x => (x, 1))
  .reduceByKey(_ + _)
  .map(case (x, y) => (y, x))
  .sortByKey(false)
  .map(case (x, y) => (y, x))
  .take(10)

所以基本上,我交换元组,按键排序,然后再次交换。然后最后取10个。我觉得重复交换不是很优雅。

所以我想知道是否有更优雅的方式来做到这一点。

我搜索并发现有人使用 Scala implicits 将 RDD 转换为 Scala 序列,然后执行 sortByValue,但我不想将 RDD 转换为 Scala Seq,因为那会杀死RDD 的分布式特性。

那么有没有更好的办法呢?

【问题讨论】:

  • “最近我被要求找出 rdd 中出现频率最高的 10 个单词” 是的,对,“我的课程的作业被问到......”也许?
  • 是的。这是一项任务。我完成了它,结果如上所示。我不是要求任何人完成任务。我在问如何改进已经被接受为有效且正确的答案。但我觉得可以有更好的方法。
  • 好的。值得一提的是,否则您似乎正在寻找 SO 来回答您的任务
  • 不是真的。我在我的问题中发布了一个可行的解决方案。我对反复交换不太满意。
  • 我只是说先说这是一个作业。我同意(现在你已经添加了 cmets)你没有得到 SO 的回答

标签: scala apache-spark rdd


【解决方案1】:

这个怎么样:

wordsRdd.
    map(x => (x, 1)).
    reduceByKey(_ + _).
    takeOrdered(10)(Ordering.by(-1 * _._2))

或者更详细一点:

object WordCountPairsOrdering extends Ordering[(String, Int)] {
    def compare(a: (String, Int), b: (String, Int)) = b._2.compare(a._2)
}

wordsRdd.
    map(x => (x, 1)).
    reduceByKey(_ + _).
    takeOrdered(10)(WordCountPairsOrdering)

【讨论】:

  • 是的。这比我的解决方案要好得多。因为你是排序一次而不是交换,排序然后交换。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-06-23
  • 2019-10-07
  • 1970-01-01
  • 2018-09-05
  • 2016-04-11
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
相关资源
最近更新 更多