Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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[String]转换为数据帧_Scala_Apache Spark_Dataframe_Rdd - Fatal编程技术网

Scala 将RDD[String]转换为数据帧

Scala 将RDD[String]转换为数据帧,scala,apache-spark,dataframe,rdd,Scala,Apache Spark,Dataframe,Rdd,我有一个RDD[String]和这个表单: VAR1,VAR2,VAR3,VAR4, ... a , b , c , d , ... e , f , g , h , ... 这意味着第一行是以逗号分隔的标题,下面所有的行都是以逗号分隔的数据 我的目的是将非结构化RDD转换为如下数据帧: _____________________ |VAR1|VAR2|VAR3|VAR4| |----|----|----|----| | a | b | c | d | | e

我有一个RDD[String]和这个表单:

VAR1,VAR2,VAR3,VAR4, ...
  a ,  b ,  c ,  d , ...
  e ,  f ,  g ,  h , ...
这意味着第一行是以逗号分隔的标题,下面所有的行都是以逗号分隔的数据

我的目的是将非结构化RDD转换为如下数据帧:

_____________________
|VAR1|VAR2|VAR3|VAR4| 
|----|----|----|----|
|  a |  b |  c |  d | 
|  e |  f |  g |  h | 
我尝试使用方法toDF,它将RDD[元组]转换为数据帧。但是从RDD[String]到RDD[tuples]的转换听起来不现实,因为我的变量数量超过了200个

另一个解决方案应该是使用该方法

sqlContext.createDataFrame(rdd, schema)
这需要将我的RDD[String]转换为RDD[Row],并将RDD的头一行转换为schema:StructType,但我不知道如何创建该schema

任何将RDD[String]转换为带有标头的数据帧的解决方案都非常好


提前感谢。

可以从第一行创建架构:

val data = Seq(
  ("VAR1, VAR2, VAR3, VAR4"),
  ("a, b, c, d"),
  ("ae, f, g, h")
)
val rdd = sparkContext.parallelize(data).map(_.split(","))

val firstRow = rdd.first()
val schemaFields = firstRow.map(n => StructField(n, StringType, true))

val remaining = rdd.zipWithIndex().filter(_._2 > 0).keys.map(v => Row(v.toSeq: _*))
val result = spark.createDataFrame(remaining, StructType(schemaFields))
result.show(false)
输出为:

+----+-----+-----+-----+
|VAR1| VAR2| VAR3| VAR4|
+----+-----+-----+-----+
|a   | b   | c   | d   |
|ae  | f   | g   | h   |
+----+-----+-----+-----+

您也可以通过以下方式实现此结果:

val data = Seq(
  ("VAR1, VAR2, VAR3, VAR4"),
  ("a, b, c, d"),
  ("ae, f, g, h")
)

val dataDS = sc.parallelize(data).toDS
val result = spark.read.option("inferSchema","true").option("header","true").csv(dataDS)

result.printSchema

result.show
上面的输出是:

root
 |-- VAR1: string (nullable = true)
 |--  VAR2: string (nullable = true)
 |--  VAR3: string (nullable = true)
 |--  VAR4: string (nullable = true)

如果您的数据在其中一列(不包括标题)中包含数字,则Infreschema应将该列正确推断为数字类型。 例如,将其用作输入数据:

val data = Seq(
  ("VAR1, VAR2, VAR3, VAR4"),
  ("a,   1, c, d"),
  ("ae, 10, g, h")
)
输出将是:

root
 |-- VAR1: string (nullable = true)
 |--  VAR2: double (nullable = true)
 |--  VAR3: string (nullable = true)
 |--  VAR4: string (nullable = true)

我希望这有帮助

root
 |-- VAR1: string (nullable = true)
 |--  VAR2: double (nullable = true)
 |--  VAR3: string (nullable = true)
 |--  VAR4: string (nullable = true)
+----+-----+-----+-----+
|VAR1| VAR2| VAR3| VAR4|
+----+-----+-----+-----+
|   a|  1.0|    c|    d|
|  ae| 10.0|    g|    h|
+----+-----+-----+-----+