2016-02-05 51 views
1

我使用apache-spark和scala通过参数聚合值如下。 这不断增加值到“列表” 是否有更有效的方式来获得关键和StatCounter列表?通过键和StatCounter进行高效的分组

val predictorRawKey = predictorRaw.map { x => 
     val param = x._1 
     val val: Double = x._2.toDouble 
     (param, val) 
    }.mapValues(num => List(num)) 
    .reduceByKey((l1, l2) => l1 ::: l2) 
    .map { x => x._1, StatCounter(x._2.iterator)) 

回答

1

对于初学者,您不应该使用reduceByKey来分组值。直接使用groupByKey省略地图侧汇总效率更高。

幸运StatCounter可以以流方式工作,没有必要到组值都:

import org.apache.spark.util.StatCounter 

val pairs = predictorRawKey.map(x => (x._1, x._2.toDouble)) 

val predictorRawKey = pairs.aggregateByKey(StatCounter(Nil))(
    (acc: StatCounter, x: Double) => acc.merge(x), 
    (acc1: StatCounter, acc2: StatCounter) => acc1.merge(acc2) 
) 
+0

哦,我真的很感激! – joshsuihn

+0

我认为reduceByKey在内部已经具有像(acc,x)=> acc.merge(x)这样的操作。您能否简单介绍一下reduceByKey和aggregateByKey之间的区别。通常,我们可以说aggregateByKey更高效(如果它稳定且快速,我会说“高效”)谢谢! – joshsuihn

+1

这完全是关于类型。 'pairs'为'RDD [(T,Double)]',predictorRawKey为'RDD [(T,StatCounter)]'。由于类型不匹配,因此不能使用'reduceByKey'。你可以把''pairs'映射到'RDD [(T,StatCounter)]'和'reduceByKey',但是没有理由创建大量的临时对象。 – zero323