我有两个RDD,格式为
{string,HashMap [long,object]}
我想对它们执行连接操作,以便相同键的hashmap在scala中合并。
RDD1-> {string1,HashMap[{long a,object},{long b,object}]
RDD2-> {string1,HashMap[{long c,object}]
加入两个RDD后,它应该像
RDD->{string1,HashMap[{long a,object},{long b,object},{long c,object}]
任何帮助都将受到赞赏,同时我也是scala和spark的新手。
答案 0 :(得分:3)
更新:更简单的方法就是获取联合,然后按键减少:
(rdd1 union rdd2).reduceByKey(_++_)
较旧的解决方案,仅供参考。这也可以通过cogroup
来完成,join
收集一个或两个RDD中的键的值(而++
将省略仅在一个原始RDD中具有键的值)。请参阅ScalaDoc。
然后,我们使用reduce
连接值列表以形成单个值列表,最后将mapValues
值(Maps)连接到单个Map。
最后两个步骤可以合并为一个val rdd1 = sc.parallelize(List("a"->Map(1->"one", 2->"two")))
val rdd2 = sc.parallelize(List("a"->Map(3->"three")))
操作:
使用此数据......
val x = (rdd1 cogroup rdd2).mapValues{ case (a,b) => (a ++ b).reduce(_++_)}
x foreach println
> (a,Map(1 -> one, 2 -> two, 3 -> three))
...在火花壳中:
{{1}}
答案 1 :(得分:1)
您可以通过加入两个RDD并将合并函数应用于地图的元组来实现:
def join [W](其他:RDD [(K,W)],numSplits:Int):RDD [(K,(V,W))] 返回包含所有具有匹配键的元素对的RDD 这个和其他。每对元素将返回为(k,(v1, v2))元组,其中(k,v1)在此,而(k,v2)在其他中。施行 整个群集中的散列连接。
def mapValues [U](f:(V)⇒U):RDD [(K,U)]传递每个值 键值对RDD通过map函数而不改变键; 这也保留了原始RDD的分区。
假设有一个函数合并,如Best way to merge two maps and sum the values of same key?
中所述def [K] merge(a:K,b:K):K = ???
可能就像
def merge(a:Map[K,V],b:Map[K,V]) = a ++ b
鉴于此,RDD可以先加入
val joined = RDD1.join(RDD2)
然后映射
val mapped = joined.mapValues( v => merge(v._1,v._2))
结果是带有(Key,合并的Map)的RDD ..