Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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 如何使用带两个RDD的键的spark intersection()或filter()?_Scala_Apache Spark_Filter_Rdd_Intersection - Fatal编程技术网

Scala 如何使用带两个RDD的键的spark intersection()或filter()?

Scala 如何使用带两个RDD的键的spark intersection()或filter()?,scala,apache-spark,filter,rdd,intersection,Scala,Apache Spark,Filter,Rdd,Intersection,我想按键使用intersection(),或在spark中使用filter() 但我真的不知道如何按键使用intersection() 因此,我尝试使用filter(),但不起作用 示例-以下是两个RDD: data1 //RDD[(String, Int)] = Array(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1)) data2 //RDD[(String, Int)] = Array(("a", 3), ("b", 5)) val d

我想按键使用
intersection()
,或在spark中使用
filter()

但我真的不知道如何按键使用
intersection()

因此,我尝试使用
filter()
,但不起作用

示例-以下是两个RDD:

data1 //RDD[(String, Int)] = Array(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1))
data2 //RDD[(String, Int)] = Array(("a", 3), ("b", 5))

val data3 = data2.map{_._1}

data1.filter{_._1 == data3}.collect //Array[(String, Int] = Array()
我想根据
data2
拥有的密钥,获得一个与
data1
具有相同密钥的(密钥、值)对

数组((“a”,1),(“a”,2),(“b”,2),(“b”,3))
是我想要的结果

是否有一种方法可以通过使用键或过滤器解决此问题

这可以通过不同的方式实现 1. <代码>广播过滤器()中的变量需要改进可伸缩性 2. <代码>协同组(类似于按键分组) 3.使用内部联接 这里
data1.join(data2)
保存具有公共键的对(内部join


对于您的问题,我认为
cogroup()
更适合。<代码>交叉段()/代码>方法将考虑数据中的键和值,并将导致空<代码> RDD < /C> > < /P> 函数
cogroup()
按键对
rdd
的值进行分组,并为我们提供
(键,vals1,vals2)
,其中
vals1
vals2
分别包含每个键的
data1
data2
的值。请注意,如果两个数据集中没有共享某个键,则
vals1
vals2
中的一个将作为空
Seq
返回,因此我们首先必须过滤掉这些元组,以到达两个
rdd
的交点

接下来,我们将获取
vals1
——其中包含公共键的
data1
中的值——并将其转换为格式
(键,数组)
。最后,我们使用
flatMapValues()
将结果解压为
(键,值)
格式。


我不理解
cogroup
那么,如果我想在
cogroup
中使用函数操作,比如
val result=data1.filter(r=>bcast.value.contains(myFuncOper(r._1))
val data1 = sc.parallelize(Seq(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1)))
val data2 = sc.parallelize(Seq(("a", 3), ("b", 5)))

// broadcast data2 key list to use in filter method, which runs in executor nodes
val bcast = sc.broadcast(data2.map(_._1).collect())

val result = data1.filter(r => bcast.value.contains(r._1))


println(result.collect().toList)
//Output
List((a,1), (a,2), (b,2), (b,3))
val data1 = sc.parallelize(Seq(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1)))
val data2 = sc.parallelize(Seq(("a", 3), ("b", 5)))

val cogroupRdd: RDD[(String, (Iterable[Int], Iterable[Int]))] = data1.cogroup(data2)
/* List(
  (a, (CompactBuffer(1, 2), CompactBuffer(3))),
  (b, (CompactBuffer(2, 3), CompactBuffer(5))),
  (c, (CompactBuffer(1), CompactBuffer()))
) */

//Now filter keys which have two non empty CompactBuffer. You can do that with 
//filter(row => row._2._1.nonEmpty && row._2._2.nonEmpty) also. 
val filterRdd = cogroupRdd.filter { case (k, (v1, v2)) => v1.nonEmpty && v2.nonEmpty } 
/* List(
  (a, (CompactBuffer(1, 2), CompactBuffer(3))),
  (b, (CompactBuffer(2, 3), CompactBuffer(5)))
) */

//As we care about first data only, lets pick first compact buffer only 
// by doing v1.map(val1 => (k, val1))
val result = filterRdd.flatMap { case (k, (v1, v2)) => v1.map(val1 => (k, val1)) }
//List((a, 1), (a, 2), (b, 2), (b, 3))
val resultRdd = data1.join(data2).map(r => (r._1, r._2._1)).distinct()
//List((b,2), (b,3), (a,2), (a,1)) 
//List((a,(1,3)), (a,(2,3)), (b,(2,5)), (b,(2,1)), (b,(3,5)), (b,(3,1)))
val result = (data1.cogroup(data2)
  .filter{case (k, (vals1, vals2)) => vals1.nonEmpty && vals2.nonEmpty }
  .map{case (k, (vals1, vals2)) => (k, vals1.toArray)}
  .flatMapValues(identity[Array[Int]]))

result.collect()
// Array[(String, Int)] = Array((a,1), (a,2), (b,2), (b,3))