web-dev-qa-db-ja.com

Spark-SQL:TSVまたはCSVファイルをデータフレームに読み込んでカスタムスキーマを適用する方法

Spark 2.0を使用していて、タブ区切り値(TSV)およびコンマ区切り値(CSV)ファイルを使用しています。Spark-SQLデータフレームにデータをロードしたい場合、ファイルが読み込まれたときにスキーマを完全に制御したいSparkでファイル内のデータからスキーマを推測したくない。

TSVまたはCSVファイルをSpark SQLデータフレームにロードし、それらにスキーマを適用するにはどうすればよいですか?

以下は、完全なSpark 2.0の例で、タブ区切り値(TSV)ファイルをロードしてスキーマを適用する方法を示しています。

AH.eduのTSV形式のアイリスデータセット を例として使用しています。そのファイルの最初の数行は次のとおりです。

_Type    PW      PL      SW      SL
0       2       14      33      50
1       24      56      31      67
1       23      51      31      69
0       2       10      36      46
1       20      52      30      65
_

スキーマを適用するには、次の2つの方法のいずれかを使用して、プログラムでスキーマを構築します。

A. StructTypeを使用してスキーマを作成します。

_import org.Apache.spark.sql.types._

var irisSchema = StructType(Array(
    StructField("Type",         IntegerType, true),
    StructField("PetalWidth",   IntegerType, true),
    StructField("PetalLength",  IntegerType, true),
    StructField("SepalWidth",   IntegerType, true),
    StructField("SepalLength",  IntegerType, true)
    ))
_

B.または、_case class_およびEncodersを使用してスキーマを作成します(この方法は冗長性が低くなります)。

_import org.Apache.spark.sql.Encoders

case class IrisSchema(Type: Int, PetalWidth: Int, PetalLength: Int, 
                      SepalWidth: Int, SepalLength: Int)

var irisSchema = Encoders.product[IrisSchema].schema
_

スキーマを作成したら、_spark.read_を使用してTSVファイルを読み取ることができます。 option("delimiter", d)オプションを正しく設定していれば、実際にはカンマ区切り値(CSV)ファイルや区切りファイルも読み取ることができます。さらに、ヘッダー行があるデータファイルがある場合は、必ずoption("header", "true")を設定してください。

以下は完全な最終コードです。

_import org.Apache.spark.sql.SparkSession
import org.Apache.spark.sql.Encoders

val spark = SparkSession.builder().getOrCreate()

case class IrisSchema(Type: Int, PetalWidth: Int, PetalLength: Int,
                      SepalWidth: Int, SepalLength: Int)

var irisSchema = Encoders.product[IrisSchema].schema

var irisDf = spark.read.format("csv").     // Use "csv" regardless of TSV or CSV.
                option("header", "true").  // Does the file have a header line?
                option("delimiter", "\t"). // Set delimiter to tab or comma.
                schema(irisSchema).        // Schema that was built above.
                load("iris.tsv")

irisDf.show(5)
_

そしてここに出力があります:

_scala> irisDf.show(5)
+----+----------+-----------+----------+-----------+
|Type|PetalWidth|PetalLength|SepalWidth|SepalLength|
+----+----------+-----------+----------+-----------+
|   0|         2|         14|        33|         50|
|   1|        24|         56|        31|         67|
|   1|        23|         51|        31|         69|
|   0|         2|         10|        36|         46|
|   1|        20|         52|        30|         65|
+----+----------+-----------+----------+-----------+
only showing top 5 rows
_
17