我是scala(2.11)和spark(1.6.0)的新程序员,他试图将RDD转换为没有spark-csv包的DF(用于练习,但也因为一些技术问题)。在阅读了Spark的入门指南和stackoverflow的所有相关帖子后,我不知道如何使一些方法(4)工作 - 只有一个适合我,我不知道为什么 - :
对他们中的任何一个人的帮助都会很棒!
我有一个像txt文件中的简单表格:
Jorgito 10 1 Soltero
Juanito 20 2 Casado
Jaimito 30 3 Divociado
我编写了几个初步的代码:
var RDD_filas = RDD_datos.map(_.split("\t"))
var esquema = new StructType()
.add("Nombre", StringType)
.add("Edad", IntegerType)
.add("Hijos",IntegerType)
.add("EC",StringType)
import org.apache.spark.sql._
import org.apache.spark.sql.Row;
import org.apache.spark.sql.types.{StructType, StructField, StringType, IntegerType};
import org.apache.spark.sql.SQLContext
case class X(Nombre: String, Edad: Int, Hijos: Int, EC: String)
然后,我应用了我看到的所有不起作用的方法:
var DF_datos = RDD_filas.map({case Array(s0, s1, s2, s3) => X(s0, s1.trim.toInt, s2.trim.toInt, s3)}).toDF("Nombre","Edad","Hijos","EC")
var DF_datos2 = RDD_filas.map(p => X(p(0), p(1).trim.toInt,p(2).trim.toInt,p(3))).toDF("Nombre","Edad","Hijos","EC")
var DF_datos3 = RDD_filas.map(Array(s0, s1, s2, s3) => Array(s0, s1.trim.toInt, s2.trim.toInt, s3)).toDF("Nombre","Edad","Hijos","EC")
var DF_datos4 = sqlContext.createDataFrame(RDD_filas,esquema)
前三个方法允许我创建DF并打印他们的模式,但它们没有标题(DF_datos.header()返回第一行)如果我尝试DF_datos.show我有一个错误( ) 最奇怪的一个(对我而言)是4号,因为它应该是最“规范”的方式。
只有这对我有用:
var a = RDD_datos.map(_.split(" ")).take(3)
val rdd = sc.makeRDD(a)
val df = rdd.map {case Array(s0, s1, s2, s3) => X(s0, s1.toInt, s2.toInt, s3)}.toDF()
答案 0 :(得分:2)
要使用sqlContext.createDataFrame
,您需要拥有RDD[Row]
,其中行中条目的类型与架构中的类型相对应。因此,您需要在适当时将某些条目从String
转换为Int
。
以下是一个例子:
scala> val data = sc.textFile("./junk/dat.txt")
data: org.apache.spark.rdd.RDD[String] = ./junk/dat.txt MapPartitionsRDD[20] at textFile at <console>:28
scala> data.foreach{println}
Jorgito 10 1 Soltero
Juanito 20 2 Casado
Jaimito 30 3 Divociado
scala> :pa
// Entering paste mode (ctrl-D to finish)
var esquema = new StructType()
.add("Nombre", StringType)
.add("Edad", IntegerType)
.add("Hijos",IntegerType)
.add("EC",StringType)
// Exiting paste mode, now interpreting.
esquema: org.apache.spark.sql.types.StructType = StructType(StructField(Nombre,StringType,true), StructField(Edad,IntegerType,true), StructField(Hijos,IntegerType,true), StructField(EC,StringType,true))
scala> val rowRDD = data.map(l => l.split(" ")).map{case Array(a,b,c,d) => Row(a, b.toInt, c.toInt, d)}
rowRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[22] at map at <console>:30
scala> val df = sqlContext.createDataFrame(rowRDD, esquema)
df: org.apache.spark.sql.DataFrame = [Nombre: string, Edad: int ... 2 more fields]
scala> df.show
+-------+----+-----+---------+
| Nombre|Edad|Hijos| EC|
+-------+----+-----+---------+
|Jorgito| 10| 1| Soltero|
|Juanito| 20| 2| Casado|
|Jaimito| 30| 3|Divociado|
+-------+----+-----+---------+
然而,这是一项很多工作,所以我建议您a)升级到Spark 2.0并使用内置的DataFrameReader
csv
加载器
或b)调查spark-csv
。在这两种情况下,您只需根据需要将分隔符设置为\s
或\t
。