Spark优化字符串的计数出现次数

时间:2015-06-09 17:28:25

标签: scala apache-spark

我拿了一个字符串然后切片,所以我只有那个字符串的第一个字母。我在计算每个关键字的出现次数。我有可行的代码,但我认为它不是最优化的。我这样说是因为在python中我使用了一个名为counter的函数,它不再需要执行额外的.groupByKey(),顺便说一句,键是列号。

val firstLetter = stringRDD.map(x => (x._1, x._2.slice(0,1)))
                    .groupBy(identity).mapValues(_.size)
                    .map(x => (x._1._1, (x._1._2, x._2)))
                    .groupByKey().collect()

最后我的输出如下所示(例如Key 50,有4488个字符串以0' s开头,而key 13有4个A' s,1个D和4483 T' ; s):

firstLetter: Array[(Int, Iterable[(String, Int)])] = Array(
  (50,CompactBuffer((0,4488))), (0,CompactBuffer((D,4488))), 
  (51,CompactBuffer((X,2), (T,4486))), (32,CompactBuffer((6,4488))), 
  (13,CompactBuffer((A,4), (D,1), (T,4483))), (53,CompactBuffer((2,4488))), 
  (54,CompactBuffer((0,4488))), (14,CompactBuffer((T,4488))),       
  (45,CompactBuffer((A,4), (T,4484))), (47,CompactBuffer((2,4488))),   
  (48,CompactBuffer((0,4488))), (49,CompactBuffer((2,4488))))

示例数据:

res3: Array[(Int, String)] = Array((0,D), (13,D), (14,T), 
  (32,6393050780099594), (45,T), (47,2013-06-17 12:37:29.954597), (48,0), 
  (49,2013-06-17 12:37:29.954597), (50,0), (51,T), (53,2), 
  (54,078009959499), (0,D), (13,A), (14,T), (32,6393050780099586), (45,A),   
  (47,2013-06-17 12:37:29.718432), (48,0), (49,2013-06-17 12:37:29.718432))

业务用例:当我分析数百万条记录时,我正在查看一个姓氏为AC的文件,我注意到第13列(姓氏)有一堆不是AC的名字我可以标记这是错误的。同样,第50列是帐户名称,它们始终以0开头。

旁注:找不到太多信息,但什么是紧凑型缓冲区?

2 个答案:

答案 0 :(得分:2)

这对您有何帮助:

stringRDD.aggregateByKey(Map[Char, Int]())(
  (accum, value) => accum.get(value.head) match {
    case None => accum + (value.head -> 1)
    case Some(count) => accum + (value.head -> (count + 1))
  },
  (accum1, accum2) => accum1 ++ accum2.map{case(k,v) => k -> (v + accum1.getOrElse(k, 0))}
)

哦,这是CompactBuffer

答案 1 :(得分:0)

这个替代方案避免了问题中的第一个groupByKey,因此它应该表现得更好。我不认为我们可以避免在最后累积值 - 因为问题 - 需要按键组织所有字母计数值。

val letterByKey = rdd.map(elem => ((elem._1, elem._2.head), 1))
val letterCount = letterByKey.reduceByKey(_ + _).map{case ((key,str),count) => (key,(str,count))}
val letterCountByKey = letterCount.groupByKey()