Scala 将RDD转换为数据帧

Scala 将RDD转换为数据帧,scala,dataframe,apache-spark,rdd,Scala,Dataframe,Apache Spark,Rdd,我是spark/scala的新手。 我通过从多个路径加载数据创建了一个RDD。现在,我想从相同的数据帧创建数据帧,以便进行进一步的操作。 下面应该是dataframe的模式 schema[UserId, EntityId, WebSessionId, ProductId] rdd.foreach(println) 545456,5615615,DIKFH6545614561456,PR5454564656445454 875643,5485254,JHDSFJD543514KJKJ4 545

我是spark/scala的新手。 我通过从多个路径加载数据创建了一个RDD。现在,我想从相同的数据帧创建数据帧,以便进行进一步的操作。 下面应该是dataframe的模式

schema[UserId, EntityId, WebSessionId, ProductId]

rdd.foreach(println)

545456,5615615,DIKFH6545614561456,PR5454564656445454
875643,5485254,JHDSFJD543514KJKJ4
545456,5615615,DIKFH6545614561456,PR5454564656445454
545456,5615615,DIKFH6545614561456,PR5454564656445454
545456,5615615,DIKFH6545614561456,PR54545DSKJD541054
264264,3254564,MNXZCBMNABC5645SAD,PR5142545564542515
732543,8765984,UJHSG4240323545144
564574,6276832,KJDXSGFJFS2545DSAS
有人能帮我吗

我也尝试了同样的方法,定义了模式类,并将其映射到rdd,但得到了错误

“ArrayIndexOutOfBoundsException:3”


如果将列视为字符串,则可以使用以下内容创建:

import org.apache.spark.sql.Row

val rdd : RDD[Row] = ???

val df = spark.createDataFrame(rdd, StructType(Seq(
  StructField("userId", StringType, false),
  StructField("EntityId", StringType, false),
  StructField("WebSessionId", StringType, false),
  StructField("ProductId", StringType, true))))
请注意,必须将RDD“映射”到RDD[Row],编译器才能使用“createDataFrame”方法。对于缺少的字段,可以在DataFrame架构中将列声明为可空

在您的示例中,您使用的是RDD方法spark.sparkContext.textFile()。此方法返回一个RDD[String],表示RDD的每个元素都是一行。但是,您需要一个RDD[Row]。因此,您需要使用逗号拆分字符串,如:

val list = 
 List("545456,5615615,DIKFH6545614561456,PR5454564656445454",
   "875643,5485254,JHDSFJD543514KJKJ4", 
   "545456,5615615,DIKFH6545614561456,PR5454564656445454", 
   "545456,5615615,DIKFH6545614561456,PR5454564656445454", 
   "545456,5615615,DIKFH6545614561456,PR54545DSKJD541054", 
   "264264,3254564,MNXZCBMNABC5645SAD,PR5142545564542515", 
"732543,8765984,UJHSG4240323545144","564574,6276832,KJDXSGFJFS2545DSAS")


val FilterReadClicks = spark.sparkContext.parallelize(list)

val rows: RDD[Row] = FilterReadClicks.map(line => line.split(",")).map { arr =>
  val array = Row.fromSeq(arr.foldLeft(List[Any]())((a, b) => b :: a))
  if(array.length == 4) 
    array
  else Row.fromSeq(array.toSeq.:+(""))
}

rows.foreach(el => println(el.toSeq))

val df = spark.createDataFrame(rows, StructType(Seq(
  StructField("userId", StringType, false),
  StructField("EntityId", StringType, false),
  StructField("WebSessionId", StringType, false),
  StructField("ProductId", StringType, true))))

df.show()

+------------------+------------------+------------+---------+
|            userId|          EntityId|WebSessionId|ProductId|
+------------------+------------------+------------+---------+
|PR5454564656445454|DIKFH6545614561456|     5615615|   545456|
|JHDSFJD543514KJKJ4|           5485254|      875643|         |
|PR5454564656445454|DIKFH6545614561456|     5615615|   545456|
|PR5454564656445454|DIKFH6545614561456|     5615615|   545456|
|PR54545DSKJD541054|DIKFH6545614561456|     5615615|   545456|
|PR5142545564542515|MNXZCBMNABC5645SAD|     3254564|   264264|
|UJHSG4240323545144|           8765984|      732543|         |
|KJDXSGFJFS2545DSAS|           6276832|      564574|         |
+------------------+------------------+------------+---------+

使用rows rdd,您将能够创建数据帧。

您似乎在某些行中有3个元素,在其他行中有4个元素。这应该是异常背后的原因。是的,没错。。!!!但我正在寻找解决方法也许这能帮上忙:嗨,它以错误的形式给出错误:重载方法值createDataFrame和其他选项:编辑您的问题并添加RDD代码以查看发生了什么。val ReadClicks=c.textFile(FlumePath)\\here flume path包含多个数据源val FilterReadClicks=ReadClicks.filter(x=>(!x.isEmpty)&&&(x!=null)&&&(x.lenght>3))\\n现在我正在尝试将RDD转换为数据帧val df=spark.createDataframe(FilterReadClicks,StructType(Seq)(StructField(“userId”,StringType,false),StructField(“EntityId”),StringType,false),StructField(“WebSessionId”,StringType,false),StructField(“ProductId,StringType,true)))我如何创建RDD[Row]或者有没有办法将RDD[String]转换为RDD[Row]谢谢您的更新…但似乎运气不好。。!!我添加了建议的代码