J'ai un fichier texte sur HDFS et je veux le convertir en un cadre de données dans Spark.
J'utilise le contexte Spark pour charger le fichier, puis essayer de générer des colonnes individuelles à partir de ce fichier.
val myFile = sc.textFile("file.txt")
val myFile1 = myFile.map(x=>x.split(";"))
Après cela, je tente l'opération suivante.
myFile1.toDF()
Je reçois un problème car les éléments de myFile1 RDD sont maintenant du type tableau.
Comment puis-je résoudre ce problème?
Update - à partir de Spark 1.6, vous pouvez simplement utiliser la source de données CSV intégrée:
spark: SparkSession = // create the Spark Session
val df = spark.read.csv("file.txt")
Vous pouvez également utiliser diverses options pour contrôler l'analyse CSV, par exemple:
val df = spark.read.option("header", "false").csv("file.txt")
Pour la version <1.6: .__ de Spark, le moyen le plus simple consiste à utiliser spark-csv - l’inclure dans vos dépendances et à suivre le fichier README, ce qui permet de définir un délimiteur personnalisé (;
), capable de lire du CSV en-têtes (si vous en avez), et il peut en déduire le schéma types (avec le coût d'une analyse supplémentaire des données).
Si vous connaissez le schéma, vous pouvez également créer une classe de cas qui le représente et mapper vos éléments RDD dans des instances de cette classe avant de les transformer en un DataFrame, par exemple:
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"
J'ai donné différentes façons de créer DataFrame à partir d'un fichier texte
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()
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()
Si vous souhaitez utiliser la méthode toDF
, vous devez convertir votre RDD
de Array[String]
en RDD
d'une classe de cas. Par exemple, vous devez faire:
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()
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)
Vous ne pourrez pas le convertir en trame de données avant d’utiliser la conversion implicite.
val sqlContext = new SqlContext(new SparkContext())
import sqlContext.implicits._
Après cela, vous pourrez le convertir en trame de données.
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()
Je sais que je suis assez en retard pour répondre à cette question mais j’ai trouvé une réponse différente:
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
Vous pouvez lire un fichier pour avoir un RDD, puis lui affecter un schéma. Deux manières courantes de créer un schéma sont d'utiliser une classe de cas ou un objet Schema [mon préféré]. Suit les extraits rapides de code que vous pouvez utiliser.
Approche par classe de cas
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()
Approche de schéma
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()
La seconde est mon approche préférée car la classe de cas a une limite de 22 champs maximum, ce qui posera problème si votre fichier contient plus de 22 champs!