Scala 如何通过.map将一个RDD传递给另一个RDD
我有两个rdd,我想为rdd1的每一项计算RDD2项。因此,我在一个用户定义的函数中传递RDD2,如下所示,但我得到的错误是,Scala 如何通过.map将一个RDD传递给另一个RDD,scala,apache-spark,Scala,Apache Spark,我有两个rdd,我想为rdd1的每一项计算RDD2项。因此,我在一个用户定义的函数中传递RDD2,如下所示,但我得到的错误是,rdd1不能在另一个rdd中传递。如果我想在两个rdd上执行操作,我可以知道如何实现这一点吗 例如: RDD1.map(line=>函数(line,RDD2))正如错误所说,Spark不支持嵌套RDD。通常,您必须通过重新设计算法来解决这个问题 如何做到这一点取决于实际的用例,在函数中到底发生了什么,以及它的输出是什么 有时,使用一个RDD1.cartesian(RDD2
rdd1不能在另一个rdd中传递。如果我想在两个rdd上执行操作,我可以知道如何实现这一点吗
例如:
RDD1.map(line=>函数(line,RDD2))
正如错误所说,Spark不支持嵌套RDD。通常,您必须通过重新设计算法来解决这个问题
如何做到这一点取决于实际的用例,在函数中到底发生了什么,以及它的输出是什么
有时,使用一个RDD1.cartesian(RDD2)
,对每个元组执行操作,然后按键进行缩减,就可以了。有时,如果您有(K,V)
键入两个RDD之间的连接将起作用
如果RDD2很小,您可以始终在驱动程序中收集它,将其设置为广播变量,并在函数中使用该变量,而不是RDD2
@编辑:
例如,让我们假设您的RDD包含字符串,并且函数将计算RDD
中的给定记录在RDD2
中出现的次数:
def function(line: String, rdd: RDD[String]): (String, Int) = {
(line, rdd.filter(_ == line).count)
}
这将返回一个RDD[(字符串,Int)]
Idea1
您可以尝试使用usingrdd的笛卡尔方法
val cartesianProduct = RDD1.cartesian(RDD2) // creates RDD[(String, String)]
.map( (r1,r2) => (r1, function2) ) // creates RDD[(String, Int)]
.reduceByKey( (c1,c2) => c1 + c2 ) // final RDD[(String, Int)]
这里function2
接受r1
和r2
(它们是字符串)并返回1
,如果它们相等,则返回0
。最后的映射将产生一个RDD
,它将具有元组,其中键将是r1
中的记录,值将是总计数
问题1:但是,如果在RDD1
中有重复的字符串,这将不起作用。你得考虑一下。如果RDD1
记录有一些唯一的id,那就完美了
问题2:这确实会创建很多对(对于两个RDD中的1mln记录,它会创建大约500bln对),速度会很慢,并且很可能会导致很多错误
Idea2
我不理解您对RDD2大小lacs
的评论,因此这可能有效,也可能无效:
val rdd2array = sc.broadcast(RDD2.collect())
val result = RDD1.map(line => function(line, rdd2array))
问题:这可能会破坏你的记忆<在驱动程序上调用code>collect()
,并且来自rdd2
的所有记录都将加载到驱动程序节点上的内存中
Idea3
根据用例的不同,还有其他克服这种情况的方法,例如,与您的用例类似(双关语不是有意的)。这方面的一个替代解决方案是。感谢您的回复。我在一个RDD中有类似的用例,我有数百万行和200多列,而在另一个RDD中,我有LAC记录和列。我需要从RDD1中提取每一行,并需要对整个RDD2进行一些比较和计算。为了实现这一点,我想在RDD1中传递这个RDD2。但是如果我们不能支持spark中的嵌套RDD,那么如何克服这个问题。@RaghavendraKulkarni用一个example@MateuszDymczyk,“lac”==100000(在印度使用).非常感谢MateuszDymczyk@RaghavendraKulkarni没问题。它解决了你的问题吗?如果是的话,如果你接受这个答案,那就太酷了。如果没有,我们可以考虑一些不同的东西,如果你提供更多的细节:-)