代码之家  ›  专栏  ›  技术社区  ›  Sai

两个RDD的笛卡尔乘积和笛卡尔分解之和导致Spark(scala)?

  •  0
  • Sai  · 技术社区  · 7 年前

    我有两个RDD(Spark scala),如下所示:

    rdd1是 Array((1,Array(1,2,3)),(2,Array(1,2,4)))

    rdd2是 Array((1,Array(4,5,6)),(2,Array(3,5,6)))

    首先,我必须生成上述两个RDD的数组值的笛卡尔和求和。

    ((11,(Array(1,2,3),Array(4,5,6))),(12,(Array(1,2,3),Array(3,5,6))),(21,(Array(1,2,4),Array(4,5,6))),(22,(Array(1,2,4),Array(3,5,6))))
    

    笛卡尔和求和如下:

    Array((11,1*4+2*5+3*6) ,(12,1*3+2*5+3*6),(21,(1*4+2*5+4*6))(22,(1*3+2*5+4*6))
    

    我尝试过笛卡尔方法,如下所示:

    scala> val cart=rdd1.cartesian(rdd2)
    

    但我得到的结果是:

    Array[((Int, Array[Double]), (Int, Array[Double]))] i.e. 
    
    (((1,(Array(1,2,3))),(1,Array(4,5,6))),
      ((1,(Array(1,2,3))),(2,Array(3,5,6))),
      ((2,(Array(1,2,4))),(1,Array(4,5,6))),
      ((2,(Array(1,2,4))),(2,Array(3,5,6)))
      )
    

    请帮助我如何实现这一点

    阵列((11,1*4+2*5+3*6)、(12,1*3+2*5+3*6)、(21,(1*4+2*5+4*6))(22,(1*3+2*5+4*6))
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   akuiper    7 年前

    您只需映射 笛卡尔 ,收集键并计算两个数组的内积:

    rdd1.cartesian(rdd2).map{ 
        case ((k1, v1), (k2, v2)) => (k1, k2) -> v1.zip(v2).map(x => x._1 * x._2).reduce(_ + _) 
    }.collect
    
    // res5: Array[((Int, Int), Int)] = Array(((1,1),32), ((1,2),31), ((2,1),38), ((2,2),37))