如何从Spark中的文本文件创建DataFrame

时间:2016-04-21 10:06:32

标签: scala apache-spark dataframe apache-spark-sql rdd

我在HDFS上有一个文本文件,我想将它转换为Spark中的数据框。

我使用Spark Context加载文件,然后尝试从该文件生成单个列。

val myFile = sc.textFile("file.txt")
val myFile1 = myFile.map(x=>x.split(";"))

执行此操作后,我正在尝试以下操作。

myFile1.toDF()

我遇到了问题,因为myFile1 RDD中的元素现在是数组类型。

我该如何解决这个问题?

8 个答案:

答案 0 :(得分:15)

更新 - 从 Spark 1.6 开始,您只需使用内置的csv数据源:

spark: SparkSession = // create the Spark Session
val df = spark.read.csv("file.txt")

您还可以使用各种选项来控制CSV解析,例如:

val df = spark.read.option("header", "false").csv("file.txt")

对于Spark版本< 1.6 : 最简单的方法是使用spark-csv - 将它包含在您的依赖项中并遵循自述文件,它允许设置自定义分隔符(;),可以读取CSV标题(如果有的话),它可以推断架构类型(带有额外扫描数据的成本)。

或者,如果你知道模式,你可以创建一个表示它的case-class,并在转换成DataFrame之前将你的RDD元素映射到这个类的实例中,例如:

case class Record(id: Int, name: String)

val myFile1 = myFile.map(x=>x.split(";")).map {
  case Array(id, name) => Record(id.toInt, name)
} 

myFile1.toDF() // DataFrame will have columns "id" and "name"

答案 1 :(得分:5)

如果您想使用toDF方法,则必须将RDD Array[String]转换为案例类的RDD。例如,你必须这样做:

case class Test(id:String,filed2:String)
val myFile = sc.textFile("file.txt")
val df= myFile.map( x => x.split(";") ).map( x=> Test(x(0),x(1)) ).toDF()

答案 2 :(得分:5)

我已经提供了不同的方法来从文本文件

创建DataFrame
val conf = new SparkConf().setAppName(appName).setMaster("local")
val sc = SparkContext(conf)

原始文本文件

val file = sc.textFile("C:\\vikas\\spark\\Interview\\text.txt")
val fileToDf = file.map(_.split(",")).map{case Array(a,b,c) => 
(a,b.toInt,c)}.toDF("name","age","city")
fileToDf.foreach(println(_))

没有架构的火花会话

import org.apache.spark.sql.SparkSession
val sparkSess = 
SparkSession.builder().appName("SparkSessionZipsExample")
.config(conf).getOrCreate()

val df = sparkSess.read.option("header", 
"false").csv("C:\\vikas\\spark\\Interview\\text.txt")
df.show()

带有架构的火花会话

import org.apache.spark.sql.types._
val schemaString = "name age city"
val fields = schemaString.split(" ").map(fieldName => StructField(fieldName, 
StringType, nullable=true))
val schema = StructType(fields)

val dfWithSchema = sparkSess.read.option("header", 
"false").schema(schema).csv("C:\\vikas\\spark\\Interview\\text.txt")
dfWithSchema.show()

使用sql context

import org.apache.spark.sql.SQLContext

val fileRdd = 
sc.textFile("C:\\vikas\\spark\\Interview\\text.txt").map(_.split(",")).map{x 
=> org.apache.spark.sql.Row(x:_*)}
val sqlDf = sqlCtx.createDataFrame(fileRdd,schema)
sqlDf.show()

答案 3 :(得分:1)

val df = spark.read.textFile("abc.txt")

case class Abc (amount:Int, types: String, id:Int)  //columns and data types

val df2 = df.map(rec=>Amount(rec(0).toInt, rec(1), rec(2).toInt))
rdd2.printSchema
root
 |-- amount: integer (nullable = true)
 |-- types: string (nullable = true)
 |-- id: integer (nullable = true)

答案 4 :(得分:1)

在使用隐式转换之前,您无法将其转换为数据框。

login_model->get()

此后只能将其转换为数据框

val sqlContext = new SqlContext(new SparkContext())

import sqlContext.implicits._

答案 5 :(得分:0)

我知道我回答这个问题已经很晚了,但我提出了一个不同的答案:

val rdd = sc.textFile("/home/training/mydata/file.txt")

val text = rdd.map(lines=lines.split(",")).map(arrays=>(ararys(0),arrays(1))).toDF("id","name").show 

答案 6 :(得分:0)

您可以读取文件以获得RDD,然后为其分配架构。创建模式的两种常用方法是使用案例类或Schema对象[我的首选]。按照您可能使用的快速代码段进行操作。

案例类方法

case class Test(id:String,name:String)
val myFile = sc.textFile("file.txt")
val df= myFile.map( x => x.split(";") ).map( x=> Test(x(0),x(1)) ).toDF()

架构方法

import org.apache.spark.sql.types._
val schemaString = "id name"
val fields = schemaString.split(" ").map(fieldName => StructField(fieldName, StringType, nullable=true))
val schema = StructType(fields)

val dfWithSchema = sparkSess.read.option("header","false").schema(schema).csv("file.txt")
dfWithSchema.show()

第二个是我首选的方法,因为案例类有最多22个字段的限制,如果你的文件有超过22个字段,这将是一个问题!

答案 7 :(得分:0)

带有 PIPE (|) 分隔文件的 txt 文件可以读取为:


df = spark.read.option("sep", "|").option("header", "true").csv("s3://bucket_name/folder_path/file_name.txt")