Spark - CSV dosyası DataFrame olarak yüklensin mi?


142

Ben bir CSV kıvılcım okumak ve DataFrame olarak dönüştürmek ve ile HDFS depolamak istiyorum df.registerTempTable("table_name")

Denedim:

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

Aldığım hata:

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'da CSV dosyasını DataFrame olarak yüklemek için doğru komut nedir?


Yanıtlar:


181

spark-csv, temel Spark işlevinin bir parçasıdır ve ayrı bir kütüphane gerektirmez. Böylece sadece

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

Scala'da (bu, csv için ",", tsv vb. İçin "\ t" ifadelerinden bahseden herhangi bir format-sınırlayıcı için geçerlidir)

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


164

CSV'yi ayrıştırın ve Spark 2.x ile DataFrame / DataSet olarak yükleyin

İlk olarak, SparkSessionnesneyi varsayılan olarak başlat, kabuklarda şu şekilde kullanılabilirspark

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

CSV'yi aşağıdaki gibi yüklemek için aşağıdaki yollardan birini kullanın: DataFrame/DataSet

1. Programlı bir şekilde yapın

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

Güncelleme: Bağlantının gelecekte kesilmesi durumunda tüm seçeneklerin buraya eklenmesi

  • yol : dosyaların konumu. Spark benzer standart Hadoop globbing ifadeleri kabul edebilir.
  • başlık : true olarak ayarlandığında sütunları adlandırmak için ilk dosya satırı kullanılır ve verilere dahil edilmez. Tüm türler dize olarak kabul edilecektir. Varsayılan değer false değeridir.
  • ayırıcı : varsayılan olarak sütunlar kullanılarak sınırlandırılır, ancak sınırlayıcı herhangi bir karaktere ayarlanabilir
  • quote : varsayılan olarak tırnak işareti karakteri "dir, ancak herhangi bir karaktere ayarlanabilir. Tırnak içindeki sınırlayıcılar yok sayılır
  • escape : varsayılan olarak escape karakteri, ancak herhangi bir karaktere ayarlanabilir. Kaçan alıntı karakterler yok sayılır
  • parserLib : varsayılan olarak, bu kütüphaneyi CSV ayrıştırmada kullanmak için "tek yönlülük " olarak ayarlanabilen " ortak " değeridir .
  • mode : ayrıştırma modunu belirler. Varsayılan olarak PERMISSIVE şeklindedir. Olası değerler:
    • PERMISSIVE : tüm satırları ayrıştırmaya çalışır: eksik belirteçler için boş değerler eklenir ve fazladan belirteçler yoksayılır.
    • DROPMALFORMED : beklenenden daha az veya daha fazla belirteç içeren satırları veya şema ile eşleşmeyen belirteçleri bırakır
    • FAILFAST : herhangi bir hatalı biçimlendirilmiş satır karakter kümesiyle karşılaşırsa bir RuntimeException istisnası olur: varsayılan olarak 'UTF-8' olur ancak diğer geçerli karakter kümesi adlarına ayarlanabilir
  • inferSchema : otomatik olarak sütun türlerini ihlal eder . Verilerin üzerinden fazladan bir geçiş gerektirir ve varsayılan yorumda yanlıştır: bu karakterle başlayan satırları atla. Varsayılan "#" dır. Bunu null olarak ayarlayarak yorumları devre dışı bırakın.
  • nullValue : boş bir değeri belirten bir dize belirtir; bu dize ile eşleşen tüm alanlar DataFrame içinde null olarak ayarlanır
  • dateFormat : tarihleri ​​veya zaman damgalarını okurken kullanılacak tarih biçimini belirten bir dize belirtir. Özel tarih biçimleri java.text.SimpleDateFormat adresindeki biçimleri izler. Bu hem DateType hem de TimestampType için geçerlidir. Varsayılan olarak, java.sql.Timestamp.valueOf () ve java.sql.Date.valueOf () ile zaman ve tarihi ayrıştırmaya çalışmak anlamına gelir.

2. Bu SQL yolunu da yapabilirsiniz

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

Bağımlılıklar :

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

Spark sürümü <2.0

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

Bağımlılıklar:

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

bu oturum kovan gerektiriyor mu? Kovan hataları alıyorum.
Puneet

2
Gerek yok. Sadece spark-core_2.11ve spark-sql_2.11bir 2.0.1sürümüne gayet iyi. Mümkünse hata mesajını ekleyin.
mrsrinivas

1
sınırlandırılmış dosyayı veri çerçevesine dönüştürebilir miyiz?
Omkar

3
@OmkarPuttagunta: Evet, elbette! böyle bir şey denemek spark.read.format("csv").option("delimiter ", "|") ...
mrsrinivas

1
Diğer seçenek programmatic waykapalı bırakmaktır .format("csv")ve değiştirme .load(...ile .csv(.... optionTarafından döndürülen olarak yöntem DataFrameReader sınıfa aittir readyöntemle, loadve csvyöntemler seçenekleri çağrıldıktan sonra üzerinde etiketlenmiş olamaz bu yüzden bir dataframe döner. Bu cevap oldukça kapsamlı, ancak insanların mevcut tüm diğer CSV seçeneklerini görebilmesi için belgelere bağlanmalısınız. Spark.apache.org/docs/latest/api/scala/… *): org.apache.spark.sql.DataFrame
Davos

17

Hadoop 2.6 ve Spark 1.6 ve "veritabanları" paketi olmayan içindir.

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 ile CSV'yi şu şekilde okuyabilirsiniz

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)

6
Arasında bir fark var mı spark.read.csv(path)ve spark.read.format("csv").load(path)?
Eric

8

Java 1.8'de Bu kod snippet'i CSV dosyalarını okumak için mükemmel bir şekilde çalışıyor

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>

Java

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();

Bu birileri için yararlı olsa da. Sorunun bir Scala etiketi var.
OneCricketeer

5

Bir CSV dosyasını ayrıştırma konusunda birçok zorluk vardır, dosya boyutunun daha büyük olup olmadığını, sütun değerlerinde ayrıştırma hatalarına neden olabilecek ingilizce / escape / separator / diğer karakterler varsa eklemeye devam eder.

Daha sonra sihir kullanılan seçeneklerde. Benim için umut ve umut olanlar çoğu vaka kapsamalıdır aşağıdaki kodda:

### 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)

Umarım yardımcı olur. Daha fazla bilgi için: HTML kaynak koduna sahip CSV'yi okumak için PySpark 2'yi kullanma

Not: Yukarıdaki kod, CSV dosya okuma API'sının dahili Spark yüklenebilir paketleriyle birlikte geldiği Spark 2 API'sından alınmıştır.

Not: PySpark, Spark için bir Python sarıcıdır ve Scala / Java ile aynı API'yı paylaşır.


Çok teşekkür ederim, hayatımı kurtardın: D
Khubaib Raza

4

Penny's Spark 2 örneği, spark2'de bunu yapmanın yoludur. Bir numara daha var: seçeneği ilk olarak tarayarak, seçeneği şu inferSchemaşekilde ayarlayarak bu başlığı sizin için oluştursun:true

Burada, ayarladığınız sparkbir kıvılcım oturumu olduğunu varsayarsak, S3'te amazon tarafından barındırılan tüm Landsat görüntülerinin CSV dizin dosyasına yüklenecek işlemdir.

  /*
   * 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")

Kötü haber şu: bu dosyada bir taramayı tetikler; bu 20 + MB sıkıştırılmış CSV dosyası gibi büyük bir şey için, uzun bir mesafe bağlantısı üzerinden 30 saniye alabilir. Bunu aklınızda bulundurun: İçeri girdikten sonra şemayı manuel olarak kodlamak daha iyidir.

(kod snippet'i Apache Yazılım Lisansı 2.0 tüm belirsizlikleri önlemek için lisanslanmıştır; S3 entegrasyonunun demo / entegrasyon testi olarak yaptığım bir şey)


Bu csv yöntemini görmedim veya seçeneklere bir harita geçirmedim. Açık şema sağlamayı her zaman daha iyi kabul etti, inferSchema hızlı n kirli (aka veri bilimi) için iyi ama ETL için korkunç.
Davos

2

Scala 2.11 ve Apache 2.0 veya üstü bir kavanoz inşa ediyorsanız.

Bir sqlContextveya sparkContextnesne oluşturmaya gerek yoktur . Sadece bir SparkSessionnesne tüm ihtiyaçlar için yeterlidir.

İyi çalışan mycode aşağıdadır:

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()
  }
}

Eğer kümede çalışan durumda sadece değiştirmek .master("local")için .master("yarn")belirleyici olurken sparkBuildernesneyi

Spark Doc bunu kapsar: https://spark.apache.org/docs/2.2.0/sql-programming-guide.html


Bu mevcut cevaplarla aynı
mrsrinivas

0

POM dosyasına aşağıdaki Spark bağımlılıklarını ekleyin:

<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>

// Kıvılcım yapılandırması:

val spark = SparkSession.builder (). master ("local"). appName ("Örnek Uygulama"). getOrCreate ()

// csv dosyasını oku:

val df = spark.read.option ("başlık", "doğru"). csv ("FILE_PATH")

// Görüntü çıkışı

df.show ()


0

Sistemdeki göreli yoldan okumak için geçerli dizini almak için System.getProperty yöntemini ve göreli yolu kullanarak dosyayı yüklemek için daha fazla kullanır.

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)

kıvılcım: 2.4.4 scala: 2.11.12


0

Spark 2.4+ ile, yerel bir dizinden bir csv yüklemek istiyorsanız, 2 oturum kullanabilir ve bunu kovana yükleyebilirsiniz. İlk oturum master () yapılandırması "local [*]", ikinci oturum "thread" ve Hive etkin olarak oluşturulmalıdır.

Aşağıdakiler benim için çalıştı.

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

   }

Ne zaman koştu ile spark2-submit --master "yarn" --conf spark.ui.enabled=false testCSV.jariyi gitti ve kovandaki tablo oluşturdu.


-1

Varsayılan dosya biçimi spark.read .. ile Parquet ve dosya okuma csv neden istisna alıyorsunuz. Kullanmaya çalıştığınız api ile csv biçimini belirtin


-1

Spark 2.0+ kullanıyorsanız bunu deneyin

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

Not: - Bu çalışma herhangi bir sınırlandırılmış dosya için geçerlidir. Değeri değiştirmek için seçeneği (“ayırıcı”) kullanmanız yeterlidir.

Umarım bu yardımcı olur.


Bu, mevcut cevaplarla aynıdır
mrsrinivas

-1

Dahili Spark csv ile Spark> 2.0 için yeni SparkSession nesnesiyle kolayca yapabilirsiniz.

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

Ayarlayabileceğiniz çeşitli seçenekler vardır.

  • header: dosyanızda üstte başlık satırı bulunup bulunmadığı
  • inferSchema: şemayı otomatik olarak çıkarmak isteyip istemediğiniz. Varsayılan değertrue . Her zaman uygun veri tiplerini sağlamak için şema sağlamayı tercih ederim.
  • mode: ayrıştırma modu, PERMISSIVE, DROPMALFORMED veya FAILFAST
  • delimiter: sınırlayıcı belirtmek için varsayılan virgül (',')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.