Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 使用map函数检查一个RDD元素是否在另一个RDD元素中_Scala_Apache Spark_Closures - Fatal编程技术网

Scala 使用map函数检查一个RDD元素是否在另一个RDD元素中

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)){

我是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)){
    (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
之类的操作,因为这样的操作会将数据从分布式集群移回驱动程序应用程序

谢谢你详细的回答!谢谢你详细的回答!