Spark - 按键分组,然后按值计数

时间:2016-03-03 04:35:26

标签: scala apache-spark mapreduce rdd key-value

我使用map

中的RDD Array[String]函数创建了非唯一键值对
val kvPairs = myRdd.map(line => (line(0), line(1)))

这会生成格式数据:

1, A
1, A
1, B
2, C

我想按照它们的值对所有键进行分组,并提供这些值的计数,如下所示:

1, {(A, 2), (B, 1)}
2, {(C, 1)}

我尝试了很多不同的尝试,但我能得到的最接近的是:

kvPairs.sortByKey().countByValue()

这给出了

1, (A, 2)
1, (B, 1)
2, (C, 1)

此外,

kvPairs.groupByKey().sortByKey()

提供价值,但它仍然不存在:

1, {(A, A, B)}
2, {(C)}

我尝试将两者结合在一起:

kvPairs.countByValue().groupByKey().sortByKey()

但这会返回错误

  

错误:值groupByKey不是scala.collection.Map的成员[(String,String),Long]

1 个答案:

答案 0 :(得分:8)

直接计算对,然后分组(如果有的话):

kvPairs.map((_, 1L))
  .reduceByKey(_ + _)
  .map{ case ((k, v), cnt) => (k, (v, cnt)) }
  .groupByKey

如果你想在减少之后gropuByKey,你可能想要使用仅考虑密钥的第一个元素的自定义分区器。您可以查看RDD split and do aggregation on new RDDs以获取示例实现。