it-roy-ru.com

Как создать DataFrame из текстового файла в Spark

У меня есть текстовый файл в HDFS, и я хочу преобразовать его в фрейм данных в Spark.

Я использую Spark Context для загрузки файла, а затем пытаюсь сгенерировать отдельные столбцы из этого файла. 

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

После этого я пытаюсь выполнить следующую операцию.

myFile1.toDF()

Я получаю проблемы, так как элементы в myFile1 RDD теперь имеют тип массива.

Как я могу решить эту проблему?

10
Rahul

Update - начиная с 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 - включить его в свои зависимости и следовать README, он позволяет установить собственный разделитель (;), может читать CSV Заголовки (если они у вас есть), и это может вывести схему types (со стоимостью дополнительного сканирования данных). 

В качестве альтернативы, если вы знаете схему, вы можете создать класс case, который представляет ее, и отобразить ваши элементы RDD в экземпляры этого класса перед преобразованием в DataFrame, например:

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"
14
Tzach Zohar

Я дал разные способы создания 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

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()
5
Vikas Singh

Если вы хотите использовать метод toDF, вы должны преобразовать свой RDD из Array[String] в RDD класса case. Например, вы должны сделать:

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()
4
mgaido
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)
1
Vishal

Вы не сможете преобразовать его во фрейм данных, пока не используете неявное преобразование.

val sqlContext = new SqlContext(new SparkContext())

import sqlContext.implicits._

После этого только вы можете преобразовать это в фрейм данных

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()
1
Abhijit

Я знаю, что довольно поздно, чтобы ответить на этот вопрос, но я придумал другой ответ:

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 
0
Ankita

Вы можете прочитать файл, чтобы иметь СДР, а затем назначить ему схему. Два распространенных способа создания схемы - это использование класса case или объекта Schema [мой любимый]. Следует за быстрым фрагментом кода, который вы можете использовать.

Подход Case Class

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()

Второй - мой предпочтительный подход, так как case-класс имеет ограничение не более 22 полей, и это будет проблемой, если в вашем файле более 22 полей!

0
user9406937