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
Spark中“join”和“union”后跟“groupByKey”的区别?_Join_Apache Spark_Group By_Union_Pyspark - Fatal编程技术网

Spark中“join”和“union”后跟“groupByKey”的区别?

Spark中“join”和“union”后跟“groupByKey”的区别?,join,apache-spark,group-by,union,pyspark,Join,Apache Spark,Group By,Union,Pyspark,我找不到一个好的理由: anRDD.join(anotherRDD) 应不同于: anRDD.union(anotherRDD).groupByKey() 但是,后者给了我一个错误,而前者没有。如果绝对需要,我可以提供一个例子,但我想从功能抽象的角度来了解。我问过的任何人都不能很好地解释这一点。前者和后者有不同的结果集: 前任: (K, V).join(K, W) = (K, (V, W)) 前者的结果是equi-join,SQL类比: anRDD.K = anotherRDD.K

我找不到一个好的理由:

anRDD.join(anotherRDD)
应不同于:

anRDD.union(anotherRDD).groupByKey()

但是,后者给了我一个错误,而前者没有。如果绝对需要,我可以提供一个例子,但我想从功能抽象的角度来了解。我问过的任何人都不能很好地解释这一点。

前者和后者有不同的结果集:

  • 前任:

    (K, V).join(K, W) = (K, (V, W))
    
    前者的结果是equi-join,SQL类比:

    anRDD.K = anotherRDD.K
    
  • 后者:

    不仅包括相等联接结果,还包括来自anRDD的并集不匹配部分和另一个RDD的不匹配部分


前者和后者有不同的结果集:

  • 前任:

    (K, V).join(K, W) = (K, (V, W))
    
    前者的结果是equi-join,SQL类比:

    anRDD.K = anotherRDD.K
    
  • 后者:

    不仅包括相等联接结果,还包括来自anRDD的并集不匹配部分和另一个RDD的不匹配部分


    • 以下是我将用一些代码说明的一些要点:

      • join
        与两个RDD一起工作,每个RDD由对组成,并且具有需要匹配的相同密钥。两个RDD的值类型不需要匹配。生成的rdd将包含类型为(Key,(Value1,Value2))的条目
      • 如果
        anRDD
        anotherRDD
        具有不同类型的值,则
        anRDD.union(anotherRDD).groupByKey()将产生错误;如果键和值的类型相同,则不会产生错误。结果将是类型为(Key,Iterable[Value])的条目,其中Iterable不需要像join一样具有长度2
        
      例如:

      val rdd1 = sc.parallelize(Seq(  ("a", 1) , ("b", 1)))
      val rdd2 = sc.parallelize(Seq(  ("a", 2) , ("b", 2)))
      val rdd3 = sc.parallelize(Seq(  ("a", 2.0) , ("b", 2.0))) // different Value type
      val rdd4 = sc.parallelize(Seq(  ("a", 1) , ("b", 1), ("a", 5) , ("b", 5)))
      val rdd5 = sc.parallelize(Seq(  ("a", 2) , ("b", 2), ("a", 5) , ("b", 5)))
      
      产生以下结果:

      scala> rdd1.join(rdd2)
      res18: org.apache.spark.rdd.RDD[(String, (Int, Int))] = MapPartitionsRDD[77] at join at <console>:26
      
      scala> rdd1.union(rdd2).groupByKey
      res19: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[79] at groupByKey at <console>:26
      
      scala> rdd1.union(rdd3).groupByKey
      <console>:26: error: type mismatch;
       found   : org.apache.spark.rdd.RDD[(String, Double)]
       required: org.apache.spark.rdd.RDD[(String, Int)]
                    rdd1.union(rdd3).groupByKey
      
      编辑:OP使用的是Python,而不是Scala。Python和Scala在类型安全性方面存在差异。Scala将捕获两个RDD之间的类型不匹配,如上图所示;Python不会立即捕获它,但稍后当您尝试在错误类型的对象上应用方法时会产生隐藏的错误。记住,Spark是用Scala和Python API编写的

      事实上,我在注释中尝试了OP代码,在pyspark中,它可以处理像
      count()
      这样的简单操作。但是,如果您尝试对每个值进行平方运算(可以对整数进行平方运算,但不能对字符串进行平方运算),则会产生错误

      数据如下:注意,我列出了列表,我只有值1和0

      B = [('b',1), ('c',0)]
      C = [('b', 'bs'), ('c', 'cs')]
      anRDD = sc.parallelize(B)
      anotherRDD = sc.parallelize(C)
      
      以下是输出:

      >>> anRDD.join(anotherRDD).count()
      2
      >>> anRDD.union(anotherRDD).groupByKey().count()
      2
      >>> for y in anRDD.map(lambda (a, x): (a, x*x)).collect():
      ...   print y
      ... 
      ('b', 1)
      ('c', 0)
      >>> for y in anRDD.union(anotherRDD).map(lambda (a, x): (a, x*x)).collect():
      ...   print y
      ... 
      15/12/13 15:18:51 ERROR Executor: Exception in task 5.0 in stage 23.0 (TID 169)
      org.apache.spark.api.python.PythonException: Traceback (most recent call last):
      

      以下是我将用以下代码说明的一些要点:

      • join
        与两个RDD一起工作,每个RDD由对组成,并且具有需要匹配的相同密钥。两个RDD的值类型不需要匹配。生成的rdd将包含类型为(Key,(Value1,Value2))的条目
      • 如果
        anRDD
        anotherRDD
        具有不同类型的值,则
        anRDD.union(anotherRDD).groupByKey()将产生错误;如果键和值的类型相同,则不会产生错误。结果将是类型为(Key,Iterable[Value])的条目,其中Iterable不需要像join一样具有长度2
        
      例如:

      val rdd1 = sc.parallelize(Seq(  ("a", 1) , ("b", 1)))
      val rdd2 = sc.parallelize(Seq(  ("a", 2) , ("b", 2)))
      val rdd3 = sc.parallelize(Seq(  ("a", 2.0) , ("b", 2.0))) // different Value type
      val rdd4 = sc.parallelize(Seq(  ("a", 1) , ("b", 1), ("a", 5) , ("b", 5)))
      val rdd5 = sc.parallelize(Seq(  ("a", 2) , ("b", 2), ("a", 5) , ("b", 5)))
      
      产生以下结果:

      scala> rdd1.join(rdd2)
      res18: org.apache.spark.rdd.RDD[(String, (Int, Int))] = MapPartitionsRDD[77] at join at <console>:26
      
      scala> rdd1.union(rdd2).groupByKey
      res19: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[79] at groupByKey at <console>:26
      
      scala> rdd1.union(rdd3).groupByKey
      <console>:26: error: type mismatch;
       found   : org.apache.spark.rdd.RDD[(String, Double)]
       required: org.apache.spark.rdd.RDD[(String, Int)]
                    rdd1.union(rdd3).groupByKey
      
      编辑:OP使用的是Python,而不是Scala。Python和Scala在类型安全性方面存在差异。Scala将捕获两个RDD之间的类型不匹配,如上图所示;Python不会立即捕获它,但稍后当您尝试在错误类型的对象上应用方法时会产生隐藏的错误。记住,Spark是用Scala和Python API编写的

      事实上,我在注释中尝试了OP代码,在pyspark中,它可以处理像
      count()
      这样的简单操作。但是,如果您尝试对每个值进行平方运算(可以对整数进行平方运算,但不能对字符串进行平方运算),则会产生错误

      数据如下:注意,我列出了列表,我只有值1和0

      B = [('b',1), ('c',0)]
      C = [('b', 'bs'), ('c', 'cs')]
      anRDD = sc.parallelize(B)
      anotherRDD = sc.parallelize(C)
      
      以下是输出:

      >>> anRDD.join(anotherRDD).count()
      2
      >>> anRDD.union(anotherRDD).groupByKey().count()
      2
      >>> for y in anRDD.map(lambda (a, x): (a, x*x)).collect():
      ...   print y
      ... 
      ('b', 1)
      ('c', 0)
      >>> for y in anRDD.union(anotherRDD).map(lambda (a, x): (a, x*x)).collect():
      ...   print y
      ... 
      15/12/13 15:18:51 ERROR Executor: Exception in task 5.0 in stage 23.0 (TID 169)
      org.apache.spark.api.python.PythonException: Traceback (most recent call last):
      

      依我看,用数据来举例总是更好的。因为join处理pairsIMHO,所以最好提供数据示例。自从join与Pairs打交道以来,我用两个RDD尝试了一个
      union
      groupByKey
      ,每个RDD都有不同的值类型,它没有给我一个错误:
      B=('B',[1]),('c',[0])
      c=('B',['bs']),('rdc',['cs'])
      anRDD=sc.parallelize(B),
      anotherd=sc.parallelize(c)
      B_C_unionRDD=anRDD.union(另一个rdd.groupByKey()
      。它不会抛出错误。我理解您关于
      连接
      的结果是元组,而
      联合
      -
      分组键
      的结果是可数的观点。但即使我将iterable放入
      列表中(
      list())< /代码>,似乎不应该有任何区别。我编辑了斯卡拉和Python之间的类型安全性差异的答案。如果你觉得有用的话,请考虑一下投票。我尝试了一个<代码>联合<代码>和<代码> GypByKEY < /C> >两个RDDS,每个RDDS都有不同的值类型,并且不给我一个错误:<代码> B=((b),[1 ]),(c),[0])
      C=(('b',['bs']),('C',['cs'])
      anRDD=sc.parallelize(b)
      anotherRDD=sc.parallelize(C)
      b_C_unionRDD=anRDD.union(anotherRDD.groupByKey)()
      。它不会抛出错误。我理解您关于
      联接的结果是元组,以及
      联合的结果是iterable的观点。但即使我将iterable放入
      列表中(
      列表(),似乎不应该有任何区别。我编辑了斯卡拉和Python之间的类型安全性差异的答案。如果你觉得它有用的话,请考虑一下投票。