我有多个RDD作为结果并希望合并它们,它们具有相同的格式:
RDD(id, HashMap[String, HashMap[String, Int]])
^ ^ ^
| | |
identity category distribution of the category
以下是rdd:
的示例(1001, {age={10=3,15=5,16=8, ...}})
String
的第一个键HashMap[String, HashMap]
是统计信息的类别,HashMap[String, Int]
中的HashMap[String, HashMap]
是该类别的分布。在计算了不同类别的每个分布之后,我想通过标识合并它们,以便我可以将结果存储到数据库中。这是我目前得到的:
def mergeRDD(rdd1: RDD[(String, util.HashMap[String, Object])],
rdd2:RDD[(String, util.HashMap[String, Object])]): RDD[(String, util.HashMap[String, Object])] = {
val mergedRDD = rdd1.join(rdd2).map{
case (id, (m1, m2)) => {
m1.putAll(m2)
(id, m1)
}
}
mergedRDD
}
val mergedRDD = mergeRDD(provinceRDD, mergeRDD(mergeRDD(levelRDD, genderRDD), actionTypeRDD))
我写了一个函数mergeRDD
,这样我每次都可以合并两个rdds,但是我发现函数不是很优雅,作为scala的新手,任何鼓舞人心的人都会受到赞赏。
答案 0 :(得分:2)
我没有看到任何简单的方法来实现这一点,而没有达到性能。 原因是,您不是简单地合并两个rdd,而是希望您的hashmap在rdd联合后具有合并值。
现在,你的合并功能是错误的。在当前状态中,join实际上会执行内部联接,错过rdd中不存在于其他行中的行。
正确的方式就像是。
val mergedRDD = rdd1.union(rdd2).reduceByKey{
case (m1, m2) => {
m1.putAll(m2)
}
}
答案 1 :(得分:0)
您可以将java.util.HashMap
替换为scala.collection.immutable.Map
从那里:
val rdds = List(provinceRDD, levelRDD, genderRDD, actionTypeRDD)
val unionRDD = rdds.reduce(_ ++ _)
val mergedRDD = unionRDD.reduceByKey(_ ++ _)
这是假设类别在rdds之间不重叠。