Spark-CSVファイルをDataFrameとしてロードしますか?


140

私はスパークでCSVを読み取り、それをDataFrameとして変換し、HDFSに保存したいと思います df.registerTempTable("table_name")

私が試してみました:

scala> val df = sqlContext.load("hdfs:///csv/file/dir/file.csv")

私が得たエラー:

java.lang.RuntimeException: hdfs:///csv/file/dir/file.csv is not a Parquet file. expected magic number at tail [80, 65, 82, 49] but found [49, 59, 54, 10]
    at parquet.hadoop.ParquetFileReader.readFooter(ParquetFileReader.java:418)
    at org.apache.spark.sql.parquet.ParquetRelation2$MetadataCache$$anonfun$refresh$6.apply(newParquet.scala:277)
    at org.apache.spark.sql.parquet.ParquetRelation2$MetadataCache$$anonfun$refresh$6.apply(newParquet.scala:276)
    at scala.collection.parallel.mutable.ParArray$Map.leaf(ParArray.scala:658)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply$mcV$sp(Tasks.scala:54)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply(Tasks.scala:53)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply(Tasks.scala:53)
    at scala.collection.parallel.Task$class.tryLeaf(Tasks.scala:56)
    at scala.collection.parallel.mutable.ParArray$Map.tryLeaf(ParArray.scala:650)
    at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.compute(Tasks.scala:165)
    at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:514)
    at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:160)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Apache SparkでCSVファイルをDataFrameとしてロードする適切なコマンドは何ですか?


回答:


178

spark-csvはコアSpark機能の一部であり、別個のライブラリーを必要としません。だからあなたはただ例えば

df = spark.read.format("csv").option("header", "true").load("csvfile.csv")

scalaでは(これは、csvの場合は「、」、tsvの場合は「\ t」など、すべてのフォーマットイン区切り文字について機能します)

val df = sqlContext.read.format("com.databricks.spark.csv") .option("delimiter", ",") .load("csvfile.csv")


163

CSVを解析し、S​​park 2.xでDataFrame / DataSetとしてロードする

まず、デフォルトでSparkSessionオブジェクト初期化します。spark

val spark = org.apache.spark.sql.SparkSession.builder
        .master("local") # Change it as per your cluster
        .appName("Spark CSV Reader")
        .getOrCreate;

次のいずれかの方法でCSVをロードします DataFrame/DataSet

1.プログラムで実行する

 val df = spark.read
         .format("csv")
         .option("header", "true") //first line in file has headers
         .option("mode", "DROPMALFORMED")
         .load("hdfs:///csv/file/dir/file.csv")

更新:今後リンクが壊れる場合に備えて、ここからすべてのオプション追加します

  • path:ファイルの場所。Sparkと同様に、標準のHadoopグロビング式を受け入れることができます。
  • header:trueに設定すると、ファイルの最初の行が列の名前付けに使用され、データには含まれません。すべてのタイプは文字列と見なされます。デフォルト値はfalseです。
  • delimiter:デフォルトでは列は区切り文字を使用しますが、区切り文字は任意の文字に設定できます
  • quote:デフォルトでは、引用文字は "ですが、任意の文字に設定できます。引用符内の区切り文字は無視されます
  • escape:デフォルトでは、エスケープ文字はですが、任意の文字に設定できます。エスケープされた引用文字は無視されます
  • parserLib:デフォルトでは、CSV解析にそのライブラリを使用するために「univocity」に設定できるのは「commons」です。
  • mode:解析モードを決定します。デフォルトではPERMISSIVEです。可能な値は次のとおりです。
    • PERMISSIVE:すべての行を解析しようとします。欠落しているトークンにはnullが挿入され、余分なトークンは無視されます。
    • DROPMALFORMED:トークンが予想より少ないか多い行、またはスキーマに一致しないトークンを削除します
    • FAILFAST:不正な形式の行文字セットが検出された場合、RuntimeExceptionで中止します。デフォルトは「UTF-8」ですが、他の有効な文字セット名に設定できます
  • inferSchema:列タイプを自動的に推測します。データの追加パスが1つ必要で、デフォルトのコメントはfalseです。この文字で始まる行をスキップします。デフォルトは「#」です。これをnullに設定してコメントを無効にします。
  • nullValue:null値を示す文字列を指定します。この文字列に一致するフィールドはすべてDataFrameでnullとして設定されます
  • dateFormat:日付またはタイムスタンプを読み取るときに使用する日付形式を示す文字列を指定します。カスタム日付形式は、java.text.SimpleDateFormatの形式に従います。これは、DateTypeとTimestampTypeの両方に適用されます。デフォルトではnullです。これは、java.sql.Timestamp.valueOf()およびjava.sql.Date.valueOf()によって時刻と日付を解析しようとすることを意味します。

2. このSQL方法も使用できます

 val df = spark.sql("SELECT * FROM csv.`hdfs:///csv/file/dir/file.csv`")

依存関係

 "org.apache.spark" % "spark-core_2.11" % 2.0.0,
 "org.apache.spark" % "spark-sql_2.11" % 2.0.0,

Sparkバージョン<2.0

val df = sqlContext.read
    .format("com.databricks.spark.csv")
    .option("header", "true") 
    .option("mode", "DROPMALFORMED")
    .load("csv/file/path"); 

依存関係:

"org.apache.spark" % "spark-sql_2.10" % 1.6.0,
"com.databricks" % "spark-csv_2.10" % 1.6.0,
"com.univocity" % "univocity-parsers" % LATEST,

このセッションにはハイブが必要ですか?ハイブエラーが発生します。
Puneet

2
必要なし。のみのバージョンで問題spark-core_2.11ありません。可能であれば、エラーメッセージを追加します。spark-sql_2.112.0.1
mrsrinivas 2016年

1
パイプ区切りファイルをデータフレームに変換できますか?
Omkar 2017年

3
@OmkarPuttagunta:はい、もちろんです!このようなことを試してください spark.read.format("csv").option("delimiter ", "|") ...
mrsrinivas

1
のもう1つのオプションprogrammatic wayは、を省略して.format("csv")に置き換える.load(...こと.csv(...です。optionメソッドは、readメソッドによって返されるDataFrameReaderクラスに属します。メソッドloadcsvメソッドはデータフレームを返すため、呼び出された後にオプションをタグ付けすることはできません。この回答はかなり徹底しているが、人々が利用できる他のすべてのCSVオプション見ることができるように、あなたは、ドキュメントにリンクする必要がありspark.apache.org/docs/latest/api/scala/... *を):org.apache.spark.sql.DataFrame
ダボス

17

これは、Hadoopが2.6、Sparkが1.6で、「databricks」パッケージがないもの用です。

import org.apache.spark.sql.types.{StructType,StructField,StringType,IntegerType};
import org.apache.spark.sql.Row;

val csv = sc.textFile("/path/to/file.csv")
val rows = csv.map(line => line.split(",").map(_.trim))
val header = rows.first
val data = rows.filter(_(0) != header(0))
val rdd = data.map(row => Row(row(0),row(1).toInt))

val schema = new StructType()
    .add(StructField("id", StringType, true))
    .add(StructField("val", IntegerType, true))

val df = sqlContext.createDataFrame(rdd, schema)

12

Spark 2.0では、CSVを読み取る方法は次のとおりです

val conf = new SparkConf().setMaster("local[2]").setAppName("my app")
val sc = new SparkContext(conf)
val sparkSession = SparkSession.builder
  .config(conf = conf)
  .appName("spark session example")
  .getOrCreate()

val path = "/Users/xxx/Downloads/usermsg.csv"
val base_df = sparkSession.read.option("header","true").
  csv(path)

5
間に差があるspark.read.csv(path)とはspark.read.format("csv").load(path)
エリック

8

Java 1.8では、このコードスニペットはCSVファイルを読み取るために完全に機能しています

POM.xml

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql_2.10 -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.10</artifactId>
    <version>2.0.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.scala-lang/scala-library -->
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.11.8</version>
</dependency>
<dependency>
    <groupId>com.databricks</groupId>
    <artifactId>spark-csv_2.10</artifactId>
    <version>1.4.0</version>
</dependency>

ジャワ

SparkConf conf = new SparkConf().setAppName("JavaWordCount").setMaster("local");
// create Spark Context
SparkContext context = new SparkContext(conf);
// create spark Session
SparkSession sparkSession = new SparkSession(context);

Dataset<Row> df = sparkSession.read().format("com.databricks.spark.csv").option("header", true).option("inferSchema", true).load("hdfs://localhost:9000/usr/local/hadoop_data/loan_100.csv");

        //("hdfs://localhost:9000/usr/local/hadoop_data/loan_100.csv");
System.out.println("========== Print Schema ============");
df.printSchema();
System.out.println("========== Print Data ==============");
df.show();
System.out.println("========== Print title ==============");
df.select("title").show();

これは誰かに役立つかもしれませんが。質問にはScalaタグがあります。
OneCricketeer

5

CSVファイルの解析には多くの課題があります。ファイルサイズが大きい場合、列の値に英語以外/エスケープ/セパレータ/その他の文字がある場合、解析エラーの原因となる可能性があります。

魔法はそれから使用されるオプションにあります。私のために働いて、ほとんどのエッジケースをカバーすることを望んでいるものは、以下のコードにあります:

### Create a Spark Session
spark = SparkSession.builder.master("local").appName("Classify Urls").getOrCreate()

### Note the options that are used. You may have to tweak these in case of error
html_df = spark.read.csv(html_csv_file_path, 
                         header=True, 
                         multiLine=True, 
                         ignoreLeadingWhiteSpace=True, 
                         ignoreTrailingWhiteSpace=True, 
                         encoding="UTF-8",
                         sep=',',
                         quote='"', 
                         escape='"',
                         maxColumns=2,
                         inferSchema=True)

お役に立てば幸いです。詳細情報:PySpark 2を使用してHTMLソースコードを持つCSVを読み取る

注:上記のコードはSpark 2 APIからのものです。CSVファイル読み取りAPIは、Sparkのインストール可能な組み込みパッケージにバンドルされています。

注:PySparkはSparkのPythonラッパーであり、Scala / Javaと同じAPIを共有します。


ありがとうございます。あなたは私の命を救いました:D
Khubaib Raza

4

ペニーのスパーク2の例は、spark2でそれを行う方法です。もう1つのトリックがあります。データの初期スキャンを実行し、オプションinferSchematrue

ここで、spark設定したスパークセッションであると仮定すると、S3でamazonがホストするすべてのLandsatイメージのCSVインデックスファイルにロードする操作です。

  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */

val csvdata = spark.read.options(Map(
    "header" -> "true",
    "ignoreLeadingWhiteSpace" -> "true",
    "ignoreTrailingWhiteSpace" -> "true",
    "timestampFormat" -> "yyyy-MM-dd HH:mm:ss.SSSZZZ",
    "inferSchema" -> "true",
    "mode" -> "FAILFAST"))
  .csv("s3a://landsat-pds/scene_list.gz")

悪いニュースは次のとおりです。これにより、ファイル全体のスキャンがトリガーされます。この20 MB以上の圧縮されたCSVファイルのような大きなものの場合、長時間の接続では30秒かかることがあります。それを覚えておいてください:スキーマを取得したら、手動でスキーマをコーディングする方がよいでしょう。

(すべてのあいまいさを回避するためにライセンスされたコードスニペットApacheソフトウェアライセンス2.0。S3統合のデモ/統合テストとして私が行ったもの)


私はこのcsvメソッドを見たり、オプションにマップを渡したりしていません。明示的なスキーマを提供する方が常に良いと考えられています。inferSchemaは、クイックnダーティ(データサイエンス)には適していますが、ETLにはひどいものです。
ダボス

2

Scala 2.11とApache 2.0以上でjarをビルドしている場合。

sqlContextまたはsparkContextオブジェクトを作成する必要はありません。ただ、SparkSessionオブジェクトは、すべてのニーズのための要件をすれば良いです。

以下は、正常に機能するmycodeです。

import org.apache.spark.sql.{DataFrame, Row, SQLContext, SparkSession}
import org.apache.log4j.{Level, LogManager, Logger}

object driver {

  def main(args: Array[String]) {

    val log = LogManager.getRootLogger

    log.info("**********JAR EXECUTION STARTED**********")

    val spark = SparkSession.builder().master("local").appName("ValidationFrameWork").getOrCreate()
    val df = spark.read.format("csv")
      .option("header", "true")
      .option("delimiter","|")
      .option("inferSchema","true")
      .load("d:/small_projects/spark/test.pos")
    df.show()
  }
}

クラスターで実行している場合は、オブジェクトの定義中にに変更.master("local")します.master("yarn")sparkBuilder

Spark Docはこれをカバーしています:https : //spark.apache.org/docs/2.2.0/sql-programming-guide.html


これは既存の回答と同じです
mrsrinivas

0

以下のSpark依存関係をPOMファイルに追加します。

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.2.0</version>
</dependency>

// Spark構成:

val spark = SparkSession.builder()。master( "local")。appName( "Sample App")。getOrCreate()

// csvファイルを読み取る:

val df = spark.read.option( "header"、 "true")。csv( "FILE_PATH")

//出力を表示します

df.show()


0

システムの相対パスから読み取るには、System.getPropertyメソッドを使用して現在のディレクトリを取得し、さらにを使用して相対パスを使用してファイルをロードします。

scala> val path = System.getProperty("user.dir").concat("/../2015-summary.csv")
scala> val csvDf = spark.read.option("inferSchema","true").option("header", "true").csv(path)
scala> csvDf.take(3)

spark:2.4.4 scala:2.11.12


0

Spark 2.4以降では、ローカルディレクトリからcsvをロードする場合、2つのセッションを使用してハイブにロードできます。最初のセッションはmaster()configを「local [*]」として作成し、2番目のセッションは「yarn」とHiveを有効にして作成する必要があります。

以下のものは私のために働いた。

import org.apache.log4j.{Level, Logger}
import org.apache.spark._
import org.apache.spark.rdd._
import org.apache.spark.sql._

object testCSV { 

  def main(args: Array[String]) {
    Logger.getLogger("org").setLevel(Level.ERROR)
    val spark_local = SparkSession.builder().appName("CSV local files reader").master("local[*]").getOrCreate()

    import spark_local.implicits._
    spark_local.sql("SET").show(100,false)
    val local_path="/tmp/data/spend_diversity.csv"  // Local file
    val df_local = spark_local.read.format("csv").option("inferSchema","true").load("file://"+local_path) // "file://" is mandatory
    df_local.show(false)

    val spark = SparkSession.builder().appName("CSV HDFS").config("spark.sql.warehouse.dir", "/apps/hive/warehouse").enableHiveSupport().getOrCreate()

    import spark.implicits._
    spark.sql("SET").show(100,false)
    val df = df_local
    df.createOrReplaceTempView("lcsv")
    spark.sql(" drop table if exists work.local_csv ")
    spark.sql(" create table work.local_csv as select * from lcsv ")

   }

それを実行するとspark2-submit --master "yarn" --conf spark.ui.enabled=false testCSV.jar、うまくいき、ハイブにテーブルを作成しました。


-1

デフォルトのファイル形式は、spark.read ..を含むParquetと、ファイル読み取りcsvであるため、例外が発生します。使用しようとしているAPIでCSV形式を指定してください


-1

Spark 2.0以降を使用している場合は、これを試してください

For non-hdfs file:
df = spark.read.csv("file:///csvfile.csv")


For hdfs file:
df = spark.read.csv("hdfs:///csvfile.csv")

For hdfs file (with different delimiter than comma:
df = spark.read.option("delimiter","|")csv("hdfs:///csvfile.csv")

注:-これは、区切り記号付きファイルで機能します。option(“ delimiter”、)を使用して値を変更するだけです。

これがお役に立てば幸いです。


これは既存の回答と同じです
mrsrinivas

-1

組み込みのSpark csvを使用すると、Spark> 2.0の新しいSparkSessionオブジェクトで簡単に実行できます。

val df = spark.
        read.
        option("inferSchema", "false").
        option("header","true").
        option("mode","DROPMALFORMED").
        option("delimiter", ";").
        schema(dataSchema).
        csv("/csv/file/dir/file.csv")
df.show()
df.printSchema()

設定できるさまざまなオプションがあります。

  • header:ファイルの上部にヘッダー行が含まれているかどうか
  • inferSchema:スキーマを自動的に推測するかどうか。デフォルトはtrueです。私は常に適切なデータ型を確保するためにスキーマを提供することを好みます。
  • mode:解析モード、PERMISSIVE、DROPMALFORMED、またはFAILFAST
  • delimiter:区切り文字を指定する場合、デフォルトはコンマ( '、')です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.