在减少阶段更改密钥

时间:2018-01-30 02:40:43

标签: java apache-spark mapreduce

假设我的(键,值)对现在是这样的:

(word1,d1=1)
(word1,d2=1)
(word2,d1=2)
(word3,d1=1)

是否可以将密钥更改为以下值,并且值是原始数量/次数?

(word1@d1, 1/2)
(word1@d2, 1/2)
(word2@d1, 2/1)
(word3@d1, 1/1)

我从Spark阅读了文档。 reduceByKey()将返回(K,V)的数据集,其中V1,V2 - > V和密钥将保持为K.但在上述情况下,K将为K',我必须为不同的密钥更新V.我能以任何方式实现上述目标吗?刚开始学习Spark,我现在很困惑。感谢您的帮助!!

1 个答案:

答案 0 :(得分:0)

连接全局字数可以使用countByKey(广播连接)和标准join来完成。不清楚什么是类型,所以我们假设:

val sc: SparkContext

val rdd = sc.parallelize(Seq(
  ("word1", "d1=1"), ("word1", "d2=1"), ("word2", "d1=2"), ("word3", "d1=1")
))

使用countByKey

val cnts = sc.broadcast(rdd.countByKey)

map

rdd.map { case (k, v) => (k, (v, cnts.value.getOrElse(k, 0L))) }

collected给出:

Array((word1,(d1=1,2)), (word1,(d2=1,2)), (word2,(d1=2,1)), (word3,(d1=1,1)))

使用join

val cntsRDD = rdd.mapValues(_ => 1L).reduceByKey(_ + _)
rdd.join(cntsRDD)

collected给出:

Array((word2,(d1=2,1)), (word3,(d1=1,1)), (word1,(d1=1,2)), (word1,(d2=1,2)))

我将根据确切的输入类型对结果进行重新整形,作为用户的练习。