web-dev-qa-db-ja.com

SparkでテキストファイルからDataFrameを作成する方法

HDFSにテキストファイルがあり、それをSparkのデータフレームに変換したい。

Sparkコンテキストを使用してファイルをロードし、そのファイルから個々の列を生成しようとしています。

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

これを行った後、次の操作を試みています。

myFile1.toDF()

MyFile1 RDDの要素が配列型になったため、問題が発生しています。

この問題を解決するにはどうすればよいですか?

14
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")

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

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

テキストファイルから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()
6
Vikas Singh

暗黙的な変換を使用するまで、データフレームに変換することはできません。

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

ファイルを読み込んで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を超えるフィールドがある場合、これは問題になります。

0
user9406937