将数据帧转换为Spark

时间:2016-03-26 19:19:36

标签: scala dictionary apache-spark

所以,我在Spark中有一个DataFrame,如下所示:

它有30列:只显示其中的一些!

[ABCD,color,NORMAL,N,2015-02-20,1]
[XYZA,color,NORMAL,N,2015-05-04,1]
[GFFD,color,NORMAL,N,2015-07-03,1]
[NAAS,color,NORMAL,N,2015-08-26,1]
[LOWW,color,NORMAL,N,2015-09-26,1]
[KARA,color,NORMAL,N,2015-11-08,1]
[ALEQ,color,NORMAL,N,2015-12-04,1]
[VDDE,size,NORMAL,N,2015-12-23,1]
[QWER,color,NORMAL,N,2016-01-18,1]
[KDSS,color,NORMAL,Y,2015-08-29,1]
[KSDS,color,NORMAL,Y,2015-08-29,1]
[ADSS,color,NORMAL,Y,2015-08-29,1]
[BDSS,runn,NORMAL,Y,2015-08-29,1]
[EDSS,color,NORMAL,Y,2015-08-29,1]

因此,我必须将此dataFrame转换为Scala中的键值对,使用该键作为Dataframe中的一些列,并为从索引0到计数(不同键数)的键分配唯一值

例如:使用上面的案例,我想在Scala中的map(键值)集合中输出如下:

    ([ABC_color_NORMAL_N_1->0]
    [XYZA_color_NORMAL_N_1->1]
    [GFFD_color_NORMAL_N_1->2]
    [NAAS_color_NORMAL_N_1->3]
    [LOWW_color_NORMAL_N_1->4]
    [KARA_color_NORMAL_N_1->5]
    [ALEQ_color_NORMAL_N_1->6]
    [VDDE_size_NORMAL_N_1->7]
    [QWER_color_NORMAL_N_1->8]
    [KDSS_color_NORMAL_Y_1->9]
    [KSDS_color_NORMAL_Y_1->10]
    [ADSS_color_NORMAL_Y_1->11]
    [BDSS_runn_NORMAL_Y_1->12]
    [EDSS_color_NORMAL_Y_1->13]
    )

我是Scala和Spark的新手,我尝试过像这样的事情。

 var map: Map[String, Int] = Map()
    var i = 0
    dataframe.foreach( record =>{
    //Is there a better way of creating a key!
        val key = record(0) + record(1) + record(2) + record(3)
        var index = i
        map += (key -> index)
        i+=1
          }
        )

但是,这不起作用。:完成后,Map为null。

1 个答案:

答案 0 :(得分:14)

代码中的主要问题是尝试修改 workers 上执行的代码中在驱动程序端创建的变量。使用Spark时,您可以将RDD转换中的驱动程序端变量仅用作"只读"值。

具体做法是:

  • 地图是在驱动程序计算机上创建的
  • 地图(及其初始值为空)是序列化并发送到工作节点
  • 每个节点可能会更改地图(本地)
  • foreach完成后结果被丢弃 - 结果是被发送回驱动程序。

要解决此问题 - 您应该选择一个返回已更改RDD的转换(例如map)来创建密钥,使用zipWithIndex添加正在运行的" ID"和然后使用collectAsMap将所有数据作为Map获取回驱动程序:

val result: Map[String, Long] = dataframe
  .map(record => record(0) + record(1) + record(2) + record(3))
  .zipWithIndex()
  .collectAsMap()

关于密钥创建本身 - 假设您要包含前5列,并在它们之间添加分隔符(_),您可以使用:

record => record.toList.take(5).mkString("_")