Scala 使用map函数检查一个RDD元素是否在另一个RDD元素中
我是Spark的新手,对闭包很好奇。Scala 使用map函数检查一个RDD元素是否在另一个RDD元素中,scala,apache-spark,closures,Scala,Apache Spark,Closures,我是Spark的新手,对闭包很好奇。 我有两个RDD,一个包含ID和值的列表,另一个包含选定ID的列表。 如果另一个RDD包含它的ID,我想使用映射来增加元素的值,如下所示 val ids = sc.parallelize(List(1,2,10,5)) val vals = sc.parallelize(List((1, 0), (2, 0), (3,0), (4,0))) vals.map( v => { if(ids.collect().contains(v._1)){
我有两个RDD,一个包含ID和值的列表,另一个包含选定ID的列表。
如果另一个RDD包含它的ID,我想使用映射来增加元素的值,如下所示
val ids = sc.parallelize(List(1,2,10,5))
val vals = sc.parallelize(List((1, 0), (2, 0), (3,0), (4,0)))
vals.map( v => {
if(ids.collect().contains(v._1)){
(v._1, 1)
}
})
然而,作业挂起,永远不会完成。
正确的方法是什么,
谢谢你的帮助 您的实现尝试在用于映射另一个的闭包内使用一个RDD(
id
),这在Spark应用程序中是不允许的:闭包中使用的任何内容都必须是可序列化的(最好是小的),因为它将被序列化并发送给每个工作进程
这些RDD之间的leftOuterJoin
应该可以满足您的需求:
val ids = sc.parallelize(List(1,2,10,5))
val vals = sc.parallelize(List((1, 0), (2, 0), (3,0), (4,0)))
val result = vals
.leftOuterJoin(ids.keyBy(i => i))
.mapValues({
case (v, Some(matchingId)) => v + 1 // increase value if match found
case (v, None) => v // leave value as-is otherwise
})
leftOuterJoin
需要两个键值RDD,因此我们使用identity函数从ids
RDD中人工提取一个键。然后我们将每个结果(id:Int,(value:Int,matchingId:Option[Int])记录的值映射到v或v+1中
一般来说,在使用Spark时,您应该尽量减少使用collect
之类的操作,因为这样的操作会将数据从分布式集群移回驱动程序应用程序 您的实现尝试在用于映射另一个的闭包内使用一个RDD(id
),这在Spark应用程序中是不允许的:闭包中使用的任何内容都必须是可序列化的(最好是小的),因为它将被序列化并发送给每个工作进程
这些RDD之间的leftOuterJoin
应该可以满足您的需求:
val ids = sc.parallelize(List(1,2,10,5))
val vals = sc.parallelize(List((1, 0), (2, 0), (3,0), (4,0)))
val result = vals
.leftOuterJoin(ids.keyBy(i => i))
.mapValues({
case (v, Some(matchingId)) => v + 1 // increase value if match found
case (v, None) => v // leave value as-is otherwise
})
leftOuterJoin
需要两个键值RDD,因此我们使用identity函数从ids
RDD中人工提取一个键。然后我们将每个结果(id:Int,(value:Int,matchingId:Option[Int])记录的值映射到v或v+1中
一般来说,在使用Spark时,您应该尽量减少使用collect
之类的操作,因为这样的操作会将数据从分布式集群移回驱动程序应用程序 谢谢你详细的回答!谢谢你详细的回答!