HDFSにテキストファイルがあり、それをSparkのデータフレームに変換したい。
Sparkコンテキストを使用してファイルをロードし、そのファイルから個々の列を生成しようとしています。
val myFile = sc.textFile("file.txt")
val myFile1 = myFile.map(x=>x.split(";"))
これを行った後、次の操作を試みています。
myFile1.toDF()
MyFile1 RDDの要素が配列型になったため、問題が発生しています。
この問題を解決するにはどうすればよいですか?
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")
For Spark version <1.6:最も簡単な方法は spark-csv -それを依存関係に含め、READMEに従ってください。カスタム区切り文字(;
)、CSVヘッダーを読み取り(所有している場合)、スキーマtypesを推測できます(データの追加スキャンのコストがかかります)。
または、スキーマを知っている場合、それを表すケースクラスを作成し、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"
toDF
メソッドを使用する場合、Array[String]
のRDD
をケースクラスの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()
テキストファイルから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()
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()
暗黙的な変換を使用するまで、データフレームに変換することはできません。
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()
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)
私はこれに答えるのにかなり遅れていることを知っていますが、別の答えを思いつきました:
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
ファイルを読み込んでRDDを作成し、スキーマを割り当てることができます。スキーマを作成する2つの一般的な方法は、ケースクラスまたはスキーマオブジェクトのいずれかを使用することです(私の好みの方法)。使用できるコードの簡単なスニペットに従います。
ケースクラスアプローチ
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フィールドの制限があるため、2番目の方法は私の推奨アプローチです。ファイルに22を超えるフィールドがある場合、これは問題になります。