计算元组中单词的出现次数

时间:2016-05-16 19:47:39

标签: scala apache-spark

我有一个类似于以下示例的数据集:

filter {
  multiline {
    pattern => "^\Timestamp"
    what => "previous"
    negate=> true
  }
  grok {
    match => ["message", "(?m)%{DATESTAMP:Timestamp}\s+%{TITLE}\s+%{MESSAGE}\s+%{MACHINE}"]
  }
}

方括号内的记录是主题标签(不包括"无")。

我正在尝试使用Spark和Scala在数据集中找到前10个主题标签。

我到目前为止:

tmj_dc_mgmt, Washington, en, 483, 457, 256, ['hiring', 'BusinessMgmt', 'Washington', 'Job']
SRiku0728, 福山市, ja, 6705, 357, 273, ['None']
BesiktaSeyma_, Akyurt, tr, 12921, 1801, 283, ['None']
AnnaKFrick, Virginia, en, 5731, 682, 1120, ['Investment', 'PPP', 'Bogota', 'jobs']
Accprimary, Manchester, en, 1650, 268, 404, ['None']
Wandii_S, Johannesburg, en, 15510, 828, 398, ['None']

我不知道如何对此进行排序并从中排名前10位,我是Scala和Spark的新手。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:6)

您可以使用自定义排序top来实现您的目标:

val r = sc.parallelize(Seq(
  "tmj_dc_mgmt, Washington, en, 483, 457, 256, ['hiring', 'BusinessMgmt', 'Washington', 'Job']",
  "SRiku0728, 福山市, ja, 6705, 357, 273, ['None']",
  "BesiktaSeyma_, Akyurt, tr, 12921, 1801, 283, ['None']",
  "AnnaKFrick, Virginia, en, 5731, 682, 1120, ['Investment', 'PPP', 'BusinessMgmt', 'Bogota', 'jobs']",
  "Accprimary, Manchester, en, 1650, 268, 404, ['None']",
  "Wandii_S, Johannesburg, en, 15510, 828, 398, ['None']",
  "Wandii_S, Johannesburg, en, 15510, 828, 398, ['Investment']"
))

val tag = ".*\\[([^\\]]*)\\]".r

val ordering = Ordering.by[(String, Int), Int](_._2)

r.collect{case tag(t) => t.split(",\\s*")}.flatMap(_.map(_.drop(1).dropRight(1))).filter(_ != "None").map(_ -> 1)
  .reduceByKey(_ + _).top(10)(ordering).foreach(println)

结果:

(BusinessMgmt,2)
(Investment,2)
(Washington,1)
(Bogota,1)
(PPP,1)
(jobs,1)
(Job,1)
(hiring,1)

(我修改了您的测试数据以说明多个值)

或者,如果不同的哈希标记适合驱动程序的内存,则可以使用countByValue而不是reduceByKey并在本地执行最终排序:

r.collect{case tag(t) => t.split(",\\s*")}.flatMap(_.map(_.drop(1).dropRight(1))).filter(_ != "None")
  .countByValue().toList.sortBy(-_._2).take(10).foreach(println)

另请注意,我使用不同的方法来提取主题标签,因为我相信您的方式会导致错误的结果(当您选择第6列时,您会得到['hiring'['Investment' ..完整列表)。

答案 1 :(得分:3)

也许您可以尝试使用sortBytake

val sorted = tmp1.sortBy({case (word, count) => count}, ascending=false)
val top = sorted.take(10)

您可以在documentation page上找到有关RDD功能的更多信息。